Merge: user can upgrade their npub -> nsec #485
William Casarin (2):
refactor: make LoginAction a bit safer
kernelkind (1):
user can upgrade their npub -> nsec
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use enostr::{FilledKeypair, FullKeypair, Keypair};
|
use enostr::{FilledKeypair, FullKeypair, Keypair};
|
||||||
use nostrdb::Ndb;
|
use nostrdb::{Ndb, Transaction};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
column::Columns,
|
column::Columns,
|
||||||
@@ -14,6 +14,7 @@ use crate::{
|
|||||||
accounts::{AccountsView, AccountsViewResponse},
|
accounts::{AccountsView, AccountsViewResponse},
|
||||||
},
|
},
|
||||||
unknowns::SingleUnkIdAction,
|
unknowns::SingleUnkIdAction,
|
||||||
|
unknowns::UnknownIds,
|
||||||
user_account::UserAccount,
|
user_account::UserAccount,
|
||||||
};
|
};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
@@ -138,27 +139,45 @@ impl Accounts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_account_pubkey(&self, pubkey: &[u8; 32]) -> bool {
|
fn contains_account(&self, pubkey: &[u8; 32]) -> Option<ContainsAccount> {
|
||||||
for account in &self.accounts {
|
for (index, account) in self.accounts.iter().enumerate() {
|
||||||
if account.pubkey.bytes() == pubkey {
|
let has_pubkey = account.pubkey.bytes() == pubkey;
|
||||||
return true;
|
let has_nsec = account.secret_key.is_some();
|
||||||
|
if has_pubkey {
|
||||||
|
return Some(ContainsAccount { has_nsec, index });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use = "UnknownIdAction's must be handled. Use .process_unknown_id_action()"]
|
#[must_use = "UnknownIdAction's must be handled. Use .process_unknown_id_action()"]
|
||||||
pub fn add_account(&mut self, account: Keypair) -> SingleUnkIdAction {
|
pub fn add_account(&mut self, account: Keypair) -> LoginAction {
|
||||||
if self.has_account_pubkey(account.pubkey.bytes()) {
|
let pubkey = account.pubkey;
|
||||||
info!("already have account, not adding {}", account.pubkey);
|
let switch_to_index = if let Some(contains_acc) = self.contains_account(pubkey.bytes()) {
|
||||||
return SingleUnkIdAction::pubkey(account.pubkey);
|
if account.secret_key.is_some() && !contains_acc.has_nsec {
|
||||||
}
|
info!(
|
||||||
|
"user provided nsec, but we already have npub {}. Upgrading to nsec",
|
||||||
|
pubkey
|
||||||
|
);
|
||||||
|
let _ = self.key_store.add_key(&account);
|
||||||
|
|
||||||
let _ = self.key_store.add_key(&account);
|
self.accounts[contains_acc.index] = account;
|
||||||
let pk = account.pubkey;
|
} else {
|
||||||
self.accounts.push(account);
|
info!("already have account, not adding {}", pubkey);
|
||||||
SingleUnkIdAction::pubkey(pk)
|
}
|
||||||
|
contains_acc.index
|
||||||
|
} else {
|
||||||
|
info!("adding new account {}", pubkey);
|
||||||
|
let _ = self.key_store.add_key(&account);
|
||||||
|
self.accounts.push(account);
|
||||||
|
self.accounts.len() - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
LoginAction {
|
||||||
|
unk: SingleUnkIdAction::pubkey(pubkey),
|
||||||
|
switch_to_index,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_accounts(&self) -> usize {
|
pub fn num_accounts(&self) -> usize {
|
||||||
@@ -217,12 +236,34 @@ pub fn process_login_view_response(
|
|||||||
manager: &mut Accounts,
|
manager: &mut Accounts,
|
||||||
response: AccountLoginResponse,
|
response: AccountLoginResponse,
|
||||||
) -> SingleUnkIdAction {
|
) -> SingleUnkIdAction {
|
||||||
let r = match response {
|
let login_action = match response {
|
||||||
AccountLoginResponse::CreateNew => {
|
AccountLoginResponse::CreateNew => {
|
||||||
manager.add_account(FullKeypair::generate().to_keypair())
|
manager.add_account(FullKeypair::generate().to_keypair())
|
||||||
}
|
}
|
||||||
AccountLoginResponse::LoginWith(keypair) => manager.add_account(keypair),
|
AccountLoginResponse::LoginWith(keypair) => manager.add_account(keypair),
|
||||||
};
|
};
|
||||||
manager.select_account(manager.num_accounts() - 1);
|
manager.select_account(login_action.switch_to_index);
|
||||||
r
|
login_action.unk
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use = "You must call process_login_action on this to handle unknown ids"]
|
||||||
|
pub struct LoginAction {
|
||||||
|
unk: SingleUnkIdAction,
|
||||||
|
pub switch_to_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LoginAction {
|
||||||
|
// Simple wrapper around processing the unknown action to expose too
|
||||||
|
// much internal logic. This allows us to have a must_use on our
|
||||||
|
// LoginAction type, otherwise the SingleUnkIdAction's must_use will
|
||||||
|
// be lost when returned in the login action
|
||||||
|
pub fn process_action(&mut self, ids: &mut UnknownIds, ndb: &Ndb, txn: &Transaction) {
|
||||||
|
self.unk.process_action(ids, ndb, txn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct ContainsAccount {
|
||||||
|
pub has_nsec: bool,
|
||||||
|
pub index: usize,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user