diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2024-11-21 16:53:17 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2024-11-21 16:53:17 +0000 |
| commit | f79014235e85554e3661b3f2a02b8fa88bc192ff (patch) | |
| tree | fceec3ff2df212148a3420af7cef81a3f818463e /src/bin/ngit/sub_commands | |
| parent | 91b0eac4daf92b7b740267ef203a1a8ba591974b (diff) | |
feat(login): overhaul login experience
* simplify login menu, making it more accessable to newcomers and
easier to select remote signer options
* enable `ngit login` to work from anywhere (not just a git repo)
* assume fresh login details saved to global git config but fallback
to local repository
* maintain local repository login via `ngit login --local`
* maintain login via CLI arguments eg `ngit send --nsec nsec123`
* nudge users to remember nsec when pasting in ncryptsec for a
better UX, whilst maintaining the option to be prompted for
password everytime
* create placeholder menu items for help menu and create account
Diffstat (limited to 'src/bin/ngit/sub_commands')
| -rw-r--r-- | src/bin/ngit/sub_commands/init.rs | 17 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/list.rs | 6 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/login.rs | 34 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/pull.rs | 2 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/push.rs | 16 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/send.rs | 27 |
6 files changed, 40 insertions, 62 deletions
diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs index aa43106..146a29c 100644 --- a/src/bin/ngit/sub_commands/init.rs +++ b/src/bin/ngit/sub_commands/init.rs | |||
| @@ -6,7 +6,7 @@ use nostr::{nips::nip01::Coordinate, FromBech32, PublicKey, ToBech32}; | |||
| 6 | use nostr_sdk::Kind; | 6 | use nostr_sdk::Kind; |
| 7 | 7 | ||
| 8 | use crate::{ | 8 | use crate::{ |
| 9 | cli::Cli, | 9 | cli::{extract_signer_cli_arguments, Cli}, |
| 10 | cli_interactor::{Interactor, InteractorPrompt, PromptInputParms}, | 10 | cli_interactor::{Interactor, InteractorPrompt, PromptInputParms}, |
| 11 | client::{fetching_with_report, get_repo_ref_from_cache, send_events, Client, Connect}, | 11 | client::{fetching_with_report, get_repo_ref_from_cache, send_events, Client, Connect}, |
| 12 | git::{nostr_url::convert_clone_url_to_https, Repo, RepoActions}, | 12 | git::{nostr_url::convert_clone_url_to_https, Repo, RepoActions}, |
| @@ -69,7 +69,8 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 69 | 69 | ||
| 70 | let repo_ref = if let Some(repo_coordinates) = repo_coordinates.clone() { | 70 | let repo_ref = if let Some(repo_coordinates) = repo_coordinates.clone() { |
| 71 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; | 71 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; |
| 72 | if let Ok(repo_ref) = get_repo_ref_from_cache(git_repo_path, &repo_coordinates).await { | 72 | if let Ok(repo_ref) = get_repo_ref_from_cache(Some(git_repo_path), &repo_coordinates).await |
| 73 | { | ||
| 73 | Some(repo_ref) | 74 | Some(repo_ref) |
| 74 | } else { | 75 | } else { |
| 75 | None | 76 | None |
| @@ -78,15 +79,11 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 78 | None | 79 | None |
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| 81 | let (signer, user_ref) = login::launch( | 82 | let (signer, user_ref, _) = login::login_or_signup( |
| 82 | &git_repo, | 83 | &Some(&git_repo), |
| 83 | &cli_args.bunker_uri, | 84 | &extract_signer_cli_arguments(cli_args).unwrap_or(None), |
| 84 | &cli_args.bunker_app_key, | ||
| 85 | &cli_args.nsec, | ||
| 86 | &cli_args.password, | 85 | &cli_args.password, |
| 87 | Some(&client), | 86 | Some(&client), |
| 88 | false, | ||
| 89 | false, | ||
| 90 | ) | 87 | ) |
| 91 | .await?; | 88 | .await?; |
| 92 | 89 | ||
| @@ -381,7 +378,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 381 | 378 | ||
| 382 | send_events( | 379 | send_events( |
| 383 | &client, | 380 | &client, |
| 384 | git_repo_path, | 381 | Some(git_repo_path), |
| 385 | vec![repo_event], | 382 | vec![repo_event], |
| 386 | user_ref.relays.write(), | 383 | user_ref.relays.write(), |
| 387 | relays.clone(), | 384 | relays.clone(), |
diff --git a/src/bin/ngit/sub_commands/list.rs b/src/bin/ngit/sub_commands/list.rs index 351896a..7717dce 100644 --- a/src/bin/ngit/sub_commands/list.rs +++ b/src/bin/ngit/sub_commands/list.rs | |||
| @@ -12,7 +12,7 @@ use nostr_sdk::Kind; | |||
| 12 | use crate::{ | 12 | use crate::{ |
| 13 | cli_interactor::{Interactor, InteractorPrompt, PromptChoiceParms, PromptConfirmParms}, | 13 | cli_interactor::{Interactor, InteractorPrompt, PromptChoiceParms, PromptConfirmParms}, |
| 14 | client::{ | 14 | client::{ |
| 15 | fetching_with_report, get_events_from_cache, get_repo_ref_from_cache, Client, Connect, | 15 | fetching_with_report, get_events_from_local_cache, get_repo_ref_from_cache, Client, Connect, |
| 16 | }, | 16 | }, |
| 17 | git::{str_to_sha1, Repo, RepoActions}, | 17 | git::{str_to_sha1, Repo, RepoActions}, |
| 18 | git_events::{ | 18 | git_events::{ |
| @@ -37,7 +37,7 @@ pub async fn launch() -> Result<()> { | |||
| 37 | 37 | ||
| 38 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; | 38 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; |
| 39 | 39 | ||
| 40 | let repo_ref = get_repo_ref_from_cache(git_repo_path, &repo_coordinates).await?; | 40 | let repo_ref = get_repo_ref_from_cache(Some(git_repo_path), &repo_coordinates).await?; |
| 41 | 41 | ||
| 42 | let proposals_and_revisions: Vec<nostr::Event> = | 42 | let proposals_and_revisions: Vec<nostr::Event> = |
| 43 | get_proposals_and_revisions_from_cache(git_repo_path, repo_ref.coordinates()).await?; | 43 | get_proposals_and_revisions_from_cache(git_repo_path, repo_ref.coordinates()).await?; |
| @@ -47,7 +47,7 @@ pub async fn launch() -> Result<()> { | |||
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | let statuses: Vec<nostr::Event> = { | 49 | let statuses: Vec<nostr::Event> = { |
| 50 | let mut statuses = get_events_from_cache( | 50 | let mut statuses = get_events_from_local_cache( |
| 51 | git_repo_path, | 51 | git_repo_path, |
| 52 | vec![ | 52 | vec![ |
| 53 | nostr::Filter::default() | 53 | nostr::Filter::default() |
diff --git a/src/bin/ngit/sub_commands/login.rs b/src/bin/ngit/sub_commands/login.rs index df7efa5..ae5efb1 100644 --- a/src/bin/ngit/sub_commands/login.rs +++ b/src/bin/ngit/sub_commands/login.rs | |||
| @@ -5,45 +5,31 @@ use crate::{ | |||
| 5 | cli::Cli, | 5 | cli::Cli, |
| 6 | client::{Client, Connect}, | 6 | client::{Client, Connect}, |
| 7 | git::Repo, | 7 | git::Repo, |
| 8 | login, | 8 | login::fresh::fresh_login_or_signup, |
| 9 | }; | 9 | }; |
| 10 | 10 | ||
| 11 | #[derive(clap::Args)] | 11 | #[derive(clap::Args)] |
| 12 | pub struct SubCommandArgs { | 12 | pub struct SubCommandArgs { |
| 13 | /// login to the local git repository only | ||
| 14 | #[arg(long, action)] | ||
| 15 | local: bool, | ||
| 16 | |||
| 13 | /// don't fetch user metadata and relay list from relays | 17 | /// don't fetch user metadata and relay list from relays |
| 14 | #[arg(long, action)] | 18 | #[arg(long, action)] |
| 15 | offline: bool, | 19 | offline: bool, |
| 16 | } | 20 | } |
| 17 | 21 | ||
| 18 | pub async fn launch(args: &Cli, command_args: &SubCommandArgs) -> Result<()> { | 22 | pub async fn launch(_args: &Cli, command_args: &SubCommandArgs) -> Result<()> { |
| 19 | let git_repo = Repo::discover().context("cannot find a git repository")?; | 23 | let git_repo = Repo::discover().context("cannot find a git repository")?; |
| 24 | // TODO show existing login on record, prompt to logout | ||
| 25 | // TODO use cli arguments to login | ||
| 20 | if command_args.offline { | 26 | if command_args.offline { |
| 21 | login::launch( | 27 | fresh_login_or_signup(&Some(&git_repo), None, command_args.local).await?; |
| 22 | &git_repo, | ||
| 23 | &args.bunker_uri, | ||
| 24 | &args.bunker_app_key, | ||
| 25 | &args.nsec, | ||
| 26 | &args.password, | ||
| 27 | None, | ||
| 28 | true, | ||
| 29 | false, | ||
| 30 | ) | ||
| 31 | .await?; | ||
| 32 | Ok(()) | 28 | Ok(()) |
| 33 | } else { | 29 | } else { |
| 34 | let client = Client::default(); | 30 | let client = Client::default(); |
| 31 | fresh_login_or_signup(&Some(&git_repo), Some(&client), command_args.local).await?; | ||
| 35 | 32 | ||
| 36 | login::launch( | ||
| 37 | &git_repo, | ||
| 38 | &args.bunker_uri, | ||
| 39 | &args.bunker_app_key, | ||
| 40 | &args.nsec, | ||
| 41 | &args.password, | ||
| 42 | Some(&client), | ||
| 43 | true, | ||
| 44 | false, | ||
| 45 | ) | ||
| 46 | .await?; | ||
| 47 | client.disconnect().await?; | 33 | client.disconnect().await?; |
| 48 | Ok(()) | 34 | Ok(()) |
| 49 | } | 35 | } |
diff --git a/src/bin/ngit/sub_commands/pull.rs b/src/bin/ngit/sub_commands/pull.rs index d79b7b1..77a65e9 100644 --- a/src/bin/ngit/sub_commands/pull.rs +++ b/src/bin/ngit/sub_commands/pull.rs | |||
| @@ -33,7 +33,7 @@ pub async fn launch() -> Result<()> { | |||
| 33 | let repo_coordinates = get_repo_coordinates(&git_repo, &client).await?; | 33 | let repo_coordinates = get_repo_coordinates(&git_repo, &client).await?; |
| 34 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; | 34 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; |
| 35 | 35 | ||
| 36 | let repo_ref = get_repo_ref_from_cache(git_repo_path, &repo_coordinates).await?; | 36 | let repo_ref = get_repo_ref_from_cache(Some(git_repo_path), &repo_coordinates).await?; |
| 37 | 37 | ||
| 38 | let logged_in_public_key = | 38 | let logged_in_public_key = |
| 39 | if let Ok(Some(npub)) = git_repo.get_git_config_item("nostr.npub", None) { | 39 | if let Ok(Some(npub)) = git_repo.get_git_config_item("nostr.npub", None) { |
diff --git a/src/bin/ngit/sub_commands/push.rs b/src/bin/ngit/sub_commands/push.rs index a77f356..aaf1009 100644 --- a/src/bin/ngit/sub_commands/push.rs +++ b/src/bin/ngit/sub_commands/push.rs | |||
| @@ -6,7 +6,7 @@ use ngit::{ | |||
| 6 | use nostr_sdk::PublicKey; | 6 | use nostr_sdk::PublicKey; |
| 7 | 7 | ||
| 8 | use crate::{ | 8 | use crate::{ |
| 9 | cli::Cli, | 9 | cli::{extract_signer_cli_arguments, Cli}, |
| 10 | client::{ | 10 | client::{ |
| 11 | fetching_with_report, get_all_proposal_patch_events_from_cache, | 11 | fetching_with_report, get_all_proposal_patch_events_from_cache, |
| 12 | get_proposals_and_revisions_from_cache, get_repo_ref_from_cache, Client, Connect, | 12 | get_proposals_and_revisions_from_cache, get_repo_ref_from_cache, Client, Connect, |
| @@ -53,7 +53,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 53 | 53 | ||
| 54 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; | 54 | fetching_with_report(git_repo_path, &client, &repo_coordinates).await?; |
| 55 | 55 | ||
| 56 | let repo_ref = get_repo_ref_from_cache(git_repo_path, &repo_coordinates).await?; | 56 | let repo_ref = get_repo_ref_from_cache(Some(git_repo_path), &repo_coordinates).await?; |
| 57 | 57 | ||
| 58 | let logged_in_public_key = | 58 | let logged_in_public_key = |
| 59 | if let Ok(Some(npub)) = git_repo.get_git_config_item("nostr.npub", None) { | 59 | if let Ok(Some(npub)) = git_repo.get_git_config_item("nostr.npub", None) { |
| @@ -166,15 +166,11 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 166 | ahead.len() | 166 | ahead.len() |
| 167 | ); | 167 | ); |
| 168 | 168 | ||
| 169 | let (signer, user_ref) = login::launch( | 169 | let (signer, user_ref, _) = login::login_or_signup( |
| 170 | &git_repo, | 170 | &Some(&git_repo), |
| 171 | &cli_args.bunker_uri, | 171 | &extract_signer_cli_arguments(cli_args).unwrap_or(None), |
| 172 | &cli_args.bunker_app_key, | ||
| 173 | &cli_args.nsec, | ||
| 174 | &cli_args.password, | 172 | &cli_args.password, |
| 175 | Some(&client), | 173 | Some(&client), |
| 176 | false, | ||
| 177 | false, | ||
| 178 | ) | 174 | ) |
| 179 | .await?; | 175 | .await?; |
| 180 | 176 | ||
| @@ -204,7 +200,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 204 | 200 | ||
| 205 | send_events( | 201 | send_events( |
| 206 | &client, | 202 | &client, |
| 207 | git_repo_path, | 203 | Some(git_repo_path), |
| 208 | patch_events, | 204 | patch_events, |
| 209 | user_ref.relays.write(), | 205 | user_ref.relays.write(), |
| 210 | repo_ref.relays.clone(), | 206 | repo_ref.relays.clone(), |
diff --git a/src/bin/ngit/sub_commands/send.rs b/src/bin/ngit/sub_commands/send.rs index fe2952f..114a021 100644 --- a/src/bin/ngit/sub_commands/send.rs +++ b/src/bin/ngit/sub_commands/send.rs | |||
| @@ -10,12 +10,12 @@ use nostr::{ | |||
| 10 | use nostr_sdk::hashes::sha1::Hash as Sha1Hash; | 10 | use nostr_sdk::hashes::sha1::Hash as Sha1Hash; |
| 11 | 11 | ||
| 12 | use crate::{ | 12 | use crate::{ |
| 13 | cli::Cli, | 13 | cli::{extract_signer_cli_arguments, Cli}, |
| 14 | cli_interactor::{ | 14 | cli_interactor::{ |
| 15 | Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms, PromptMultiChoiceParms, | 15 | Interactor, InteractorPrompt, PromptConfirmParms, PromptInputParms, PromptMultiChoiceParms, |
| 16 | }, | 16 | }, |
| 17 | client::{ | 17 | client::{ |
| 18 | fetching_with_report, get_events_from_cache, get_repo_ref_from_cache, Client, Connect, | 18 | fetching_with_report, get_events_from_local_cache, get_repo_ref_from_cache, Client, Connect, |
| 19 | }, | 19 | }, |
| 20 | git::{identify_ahead_behind, Repo, RepoActions}, | 20 | git::{identify_ahead_behind, Repo, RepoActions}, |
| 21 | git_events::{event_is_patch_set_root, event_tag_from_nip19_or_hex}, | 21 | git_events::{event_is_patch_set_root, event_tag_from_nip19_or_hex}, |
| @@ -175,21 +175,18 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs, no_fetch: bool) -> Re | |||
| 175 | } else { | 175 | } else { |
| 176 | None | 176 | None |
| 177 | }; | 177 | }; |
| 178 | let (signer, user_ref) = login::launch( | 178 | |
| 179 | &git_repo, | 179 | let (signer, user_ref, _) = login::login_or_signup( |
| 180 | &cli_args.bunker_uri, | 180 | &Some(&git_repo), |
| 181 | &cli_args.bunker_app_key, | 181 | &extract_signer_cli_arguments(cli_args).unwrap_or(None), |
| 182 | &cli_args.nsec, | ||
| 183 | &cli_args.password, | 182 | &cli_args.password, |
| 184 | Some(&client), | 183 | Some(&client), |
| 185 | false, | ||
| 186 | false, | ||
| 187 | ) | 184 | ) |
| 188 | .await?; | 185 | .await?; |
| 189 | 186 | ||
| 190 | client.set_signer(signer.clone()).await; | 187 | client.set_signer(signer.clone()).await; |
| 191 | 188 | ||
| 192 | let repo_ref = get_repo_ref_from_cache(git_repo_path, &repo_coordinates).await?; | 189 | let repo_ref = get_repo_ref_from_cache(Some(git_repo_path), &repo_coordinates).await?; |
| 193 | 190 | ||
| 194 | // oldest first | 191 | // oldest first |
| 195 | commits.reverse(); | 192 | commits.reverse(); |
| @@ -228,7 +225,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs, no_fetch: bool) -> Re | |||
| 228 | 225 | ||
| 229 | send_events( | 226 | send_events( |
| 230 | &client, | 227 | &client, |
| 231 | git_repo_path, | 228 | Some(git_repo_path), |
| 232 | events.clone(), | 229 | events.clone(), |
| 233 | user_ref.relays.write(), | 230 | user_ref.relays.write(), |
| 234 | repo_ref.relays.clone(), | 231 | repo_ref.relays.clone(), |
| @@ -370,9 +367,11 @@ async fn get_root_proposal_id_and_mentions_from_in_reply_to( | |||
| 370 | marker: _, | 367 | marker: _, |
| 371 | public_key: _, | 368 | public_key: _, |
| 372 | }) => { | 369 | }) => { |
| 373 | let events = | 370 | let events = get_events_from_local_cache( |
| 374 | get_events_from_cache(git_repo_path, vec![nostr::Filter::new().id(*event_id)]) | 371 | git_repo_path, |
| 375 | .await?; | 372 | vec![nostr::Filter::new().id(*event_id)], |
| 373 | ) | ||
| 374 | .await?; | ||
| 376 | 375 | ||
| 377 | if let Some(first) = events.iter().find(|e| e.id.eq(event_id)) { | 376 | if let Some(first) = events.iter().find(|e| e.id.eq(event_id)) { |
| 378 | if event_is_patch_set_root(first) { | 377 | if event_is_patch_set_root(first) { |