upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/lib/login/mod.rs
blob: 00dbb17ad41a949fc45adaa08d595e19fbf67461 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use std::{path::Path, sync::Arc};

use anyhow::Result;
use fresh::fresh_login_or_signup;
use nostr::PublicKey;
use nostr_sdk::{NostrSigner, Timestamp, ToBech32};

#[cfg(not(test))]
use crate::client::Client;
#[cfg(test)]
use crate::client::MockConnect;
use crate::git::{Repo, RepoActions};

pub mod existing;
mod key_encryption;
use existing::load_existing_login;
pub mod user;
use user::UserRef;
pub mod fresh;

pub async fn login_or_signup(
    git_repo: &Option<&Repo>,
    signer_info: &Option<SignerInfo>,
    password: &Option<String>,
    #[cfg(test)] client: Option<&MockConnect>,
    #[cfg(not(test))] client: Option<&Client>,
) -> Result<(Arc<dyn NostrSigner>, UserRef, SignerInfoSource)> {
    let res =
        load_existing_login(git_repo, signer_info, password, &None, client, false, true).await;
    if res.is_ok() {
        res
    } else {
        fresh_login_or_signup(git_repo, client, None, false).await
    }
}

#[derive(Clone)]
pub enum SignerInfo {
    Nsec {
        nsec: String,
        password: Option<String>,
        npub: Option<String>,
    },
    Bunker {
        bunker_uri: String,
        bunker_app_key: String,
        npub: Option<String>,
    },
}

#[derive(PartialEq, Clone)]
pub enum SignerInfoSource {
    GitLocal,
    GitGlobal,
    CommandLineArguments,
}

fn print_logged_in_as(
    user_ref: &UserRef,
    offline_mode: bool,
    source: &SignerInfoSource,
) -> Result<()> {
    if !offline_mode && user_ref.metadata.created_at.eq(&Timestamp::from(0)) {
        eprintln!("failed to find profile...");
    } else if !offline_mode && user_ref.metadata.name.eq(&user_ref.public_key.to_bech32()?) {
        eprintln!("failed to extract account name from account metadata...");
    } else if !offline_mode && user_ref.relays.created_at.eq(&Timestamp::from(0)) {
        eprintln!(
            "failed to find your relay list. consider using another nostr client to create one to enhance your nostr experience."
        );
    }
    eprintln!(
        "logged in as {}{}",
        user_ref.metadata.name,
        match source {
            SignerInfoSource::CommandLineArguments => " via cli arguments",
            SignerInfoSource::GitLocal => " to local repository",
            SignerInfoSource::GitGlobal => "",
        }
    );
    Ok(())
}

// None: in the edge case where the user is logged in via cli arguments rather
// than from git config this may be wrong. TODO: fix this
pub async fn get_likely_logged_in_user(git_repo_path: &Path) -> Result<Option<PublicKey>> {
    let git_repo = Repo::from_path(&git_repo_path.to_path_buf())?;
    Ok(
        if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? {
            if let Ok(pubic_key) = PublicKey::parse(npub) {
                Some(pubic_key)
            } else {
                None
            }
        } else {
            None
        },
    )
}

pub fn get_curent_user(git_repo: &Repo) -> Result<Option<PublicKey>> {
    Ok(
        if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? {
            if let Ok(public_key) = PublicKey::parse(npub) {
                Some(public_key)
            } else {
                None
            }
        } else {
            None
        },
    )
}