mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-19 03:33:53 +00:00
Public key import (and delete) [if you don't have a private key setup]
This commit is contained in:
parent
6b7be372da
commit
70a78551aa
@ -408,7 +408,11 @@ impl Overlord {
|
||||
}
|
||||
"generate_private_key" => {
|
||||
let mut password: String = serde_json::from_str(&bus_message.json_payload)?;
|
||||
GLOBALS.signer.write().await.generate_private_key(&password)?;
|
||||
GLOBALS
|
||||
.signer
|
||||
.write()
|
||||
.await
|
||||
.generate_private_key(&password)?;
|
||||
password.zeroize();
|
||||
GLOBALS.signer.read().await.save_through_settings().await?;
|
||||
}
|
||||
@ -417,7 +421,11 @@ impl Overlord {
|
||||
serde_json::from_str(&bus_message.json_payload)?;
|
||||
let pk = PrivateKey::try_from_bech32_string(&import_bech32)?;
|
||||
import_bech32.zeroize();
|
||||
GLOBALS.signer.write().await.set_private_key(pk, &password)?;
|
||||
GLOBALS
|
||||
.signer
|
||||
.write()
|
||||
.await
|
||||
.set_private_key(pk, &password)?;
|
||||
password.zeroize();
|
||||
GLOBALS.signer.read().await.save_through_settings().await?;
|
||||
}
|
||||
@ -426,10 +434,31 @@ impl Overlord {
|
||||
serde_json::from_str(&bus_message.json_payload)?;
|
||||
let pk = PrivateKey::try_from_hex_string(&import_hex)?;
|
||||
import_hex.zeroize();
|
||||
GLOBALS.signer.write().await.set_private_key(pk, &password)?;
|
||||
GLOBALS
|
||||
.signer
|
||||
.write()
|
||||
.await
|
||||
.set_private_key(pk, &password)?;
|
||||
password.zeroize();
|
||||
GLOBALS.signer.read().await.save_through_settings().await?;
|
||||
}
|
||||
"import_pub" => {
|
||||
let pubstr: String = serde_json::from_str(&bus_message.json_payload)?;
|
||||
let maybe_pk1 = PublicKey::try_from_bech32_string(&pubstr);
|
||||
let maybe_pk2 = PublicKey::try_from_hex_string(&pubstr);
|
||||
if maybe_pk1.is_err() && maybe_pk2.is_err() {
|
||||
*GLOBALS.status_message.write().await =
|
||||
"Public key not recognized.".to_owned();
|
||||
} else {
|
||||
let pubkey = maybe_pk1.unwrap_or_else(|_| maybe_pk2.unwrap());
|
||||
GLOBALS.signer.write().await.set_public_key(pubkey);
|
||||
GLOBALS.signer.read().await.save_through_settings().await?;
|
||||
}
|
||||
}
|
||||
"delete_pub" => {
|
||||
GLOBALS.signer.write().await.clear_public_key();
|
||||
GLOBALS.signer.read().await.save_through_settings().await?;
|
||||
}
|
||||
"save_relays" => {
|
||||
let dirty_relays: Vec<DbRelay> = GLOBALS
|
||||
.relays
|
||||
|
@ -3,35 +3,26 @@ use crate::globals::GLOBALS;
|
||||
use nostr_types::{EncryptedPrivateKey, Event, KeySecurity, PreEvent, PrivateKey, PublicKey};
|
||||
use tokio::task;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Signer {
|
||||
public: Option<PublicKey>,
|
||||
encrypted: Option<EncryptedPrivateKey>,
|
||||
private: Option<PrivateKey>,
|
||||
}
|
||||
|
||||
impl Default for Signer {
|
||||
fn default() -> Signer {
|
||||
Signer {
|
||||
public: None,
|
||||
encrypted: None,
|
||||
private: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Signer {
|
||||
pub async fn load_from_settings(&mut self) {
|
||||
let settings = GLOBALS.settings.read().await;
|
||||
*self = Signer {
|
||||
public: settings.public_key,
|
||||
encrypted: settings.encrypted_private_key.clone(),
|
||||
private: None
|
||||
private: None,
|
||||
};
|
||||
}
|
||||
|
||||
pub async fn save_through_settings(&self) -> Result<(), Error> {
|
||||
let mut settings = GLOBALS.settings.write().await;
|
||||
settings.public_key = self.public.clone();
|
||||
settings.public_key = self.public;
|
||||
settings.encrypted_private_key = self.encrypted.clone();
|
||||
settings.save().await
|
||||
}
|
||||
@ -39,12 +30,23 @@ impl Signer {
|
||||
#[allow(dead_code)]
|
||||
pub fn set_public_key(&mut self, pk: PublicKey) {
|
||||
if self.private.is_some() {
|
||||
*GLOBALS.status_message.blocking_write() = "Ignored setting of public key (private key supercedes)".to_string();
|
||||
*GLOBALS.status_message.blocking_write() =
|
||||
"Ignored setting of public key (private key supercedes)".to_string();
|
||||
} else {
|
||||
self.public = Some(pk);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn clear_public_key(&mut self) {
|
||||
if self.private.is_some() {
|
||||
*GLOBALS.status_message.blocking_write() =
|
||||
"Ignored clearing of public key (private key supercedes)".to_string();
|
||||
} else {
|
||||
self.public = None;
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn set_encrypted_private_key(&mut self, epk: EncryptedPrivateKey) {
|
||||
if self.private.is_some() && self.encrypted.is_some() {
|
||||
@ -55,7 +57,7 @@ impl Signer {
|
||||
}
|
||||
|
||||
pub fn set_private_key(&mut self, pk: PrivateKey, pass: &str) -> Result<(), Error> {
|
||||
self.encrypted = Some(pk.export_encrypted(&pass)?);
|
||||
self.encrypted = Some(pk.export_encrypted(pass)?);
|
||||
self.public = Some(pk.public_key());
|
||||
self.private = Some(pk);
|
||||
Ok(())
|
||||
@ -65,8 +67,7 @@ impl Signer {
|
||||
if self.private.is_some() {
|
||||
// ignore, already unlocked
|
||||
Ok(())
|
||||
}
|
||||
else if let Some(epk) = &self.encrypted {
|
||||
} else if let Some(epk) = &self.encrypted {
|
||||
self.private = Some(epk.decrypt(pass)?);
|
||||
Ok(())
|
||||
} else {
|
||||
@ -91,7 +92,7 @@ impl Signer {
|
||||
}
|
||||
|
||||
pub fn public_key(&self) -> Option<PublicKey> {
|
||||
self.public.clone()
|
||||
self.public
|
||||
}
|
||||
|
||||
pub fn encrypted_private_key(&self) -> Option<EncryptedPrivateKey> {
|
||||
@ -99,18 +100,14 @@ impl Signer {
|
||||
}
|
||||
|
||||
pub fn key_security(&self) -> Option<KeySecurity> {
|
||||
if let Some(pk) = &self.private {
|
||||
Some(pk.key_security())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.private.as_ref().map(|pk| pk.key_security())
|
||||
}
|
||||
|
||||
pub fn sign_preevent(&self, preevent: PreEvent, pow: Option<u8>) -> Result<Event, Error> {
|
||||
match &self.private {
|
||||
Some(pk) => match pow {
|
||||
Some(pow) => Ok(Event::new_with_pow(preevent, &pk, pow)?),
|
||||
None => Ok(Event::new(preevent, &pk)?),
|
||||
Some(pow) => Ok(Event::new_with_pow(preevent, pk, pow)?),
|
||||
None => Ok(Event::new(preevent, pk)?),
|
||||
},
|
||||
_ => Err(Error::NoPrivateKey),
|
||||
}
|
||||
|
@ -586,7 +586,8 @@ fn render_content(app: &mut GossipUi, ui: &mut Ui, tag_re: ®ex::Regex, event:
|
||||
}
|
||||
Tag::Hashtag(s) => {
|
||||
if ui.link(format!("#{}", s)).clicked() {
|
||||
*GLOBALS.status_message.blocking_write() = "Gossip doesn't have a hashtag feed yet.".to_owned();
|
||||
*GLOBALS.status_message.blocking_write() =
|
||||
"Gossip doesn't have a hashtag feed yet.".to_owned();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -84,6 +84,7 @@ struct GossipUi {
|
||||
password: String,
|
||||
import_bech32: String,
|
||||
import_hex: String,
|
||||
import_pub: String,
|
||||
replying_to: Option<Id>,
|
||||
person_view_pubkey: Option<PublicKeyHex>,
|
||||
avatars: HashMap<PublicKeyHex, TextureHandle>,
|
||||
@ -154,6 +155,7 @@ impl GossipUi {
|
||||
password: "".to_owned(),
|
||||
import_bech32: "".to_owned(),
|
||||
import_hex: "".to_owned(),
|
||||
import_pub: "".to_owned(),
|
||||
replying_to: None,
|
||||
person_view_pubkey: None,
|
||||
avatars: HashMap::new(),
|
||||
@ -253,7 +255,10 @@ impl eframe::App for GossipUi {
|
||||
egui::TopBottomPanel::bottom("status").show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
if ui
|
||||
.add(Label::new(GLOBALS.status_message.blocking_read().clone()).sense(Sense::click()))
|
||||
.add(
|
||||
Label::new(GLOBALS.status_message.blocking_read().clone())
|
||||
.sense(Sense::click()),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
*GLOBALS.status_message.blocking_write() = "".to_string();
|
||||
|
@ -36,7 +36,8 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
|
||||
&app.new_relay_url
|
||||
);
|
||||
} else {
|
||||
*GLOBALS.status_message.blocking_write() = "That's not a valid relay URL.".to_owned();
|
||||
*GLOBALS.status_message.blocking_write() =
|
||||
"That's not a valid relay URL.".to_owned();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -86,8 +86,7 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
|
||||
*GLOBALS.status_message.blocking_write() =
|
||||
"Exported key has been printed to the console standard output.".to_owned();
|
||||
}
|
||||
Err(e) =>
|
||||
*GLOBALS.status_message.blocking_write() = format!("{}", e),
|
||||
Err(e) => *GLOBALS.status_message.blocking_write() = format!("{}", e),
|
||||
}
|
||||
app.password.zeroize();
|
||||
app.password = "".to_owned();
|
||||
@ -200,9 +199,7 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
|
||||
app.password = "".to_owned();
|
||||
}
|
||||
|
||||
ui.add_space(10.0);
|
||||
ui.separator();
|
||||
ui.add_space(10.0);
|
||||
ui.add_space(20.0);
|
||||
|
||||
ui.heading("Import a hex private key");
|
||||
|
||||
@ -230,5 +227,54 @@ pub(super) fn update(app: &mut GossipUi, _ctx: &Context, _frame: &mut eframe::Fr
|
||||
app.password.zeroize();
|
||||
app.password = "".to_owned();
|
||||
}
|
||||
|
||||
ui.add_space(10.0);
|
||||
ui.separator();
|
||||
ui.add_space(10.0);
|
||||
|
||||
ui.heading("Public Key");
|
||||
ui.add_space(10.0);
|
||||
|
||||
ui.label("You can just import your public key if you only want to view events and don't want to use gossip to create events. This will allow you to (eventually) sync your follow list and follow people on gossip without copying your private key here.");
|
||||
|
||||
if let Some(pk) = GLOBALS.signer.blocking_read().public_key() {
|
||||
let pkhex: PublicKeyHex = pk.into();
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(&format!("Public Key (Hex): {}", pkhex.0));
|
||||
if ui.add(CopyButton {}).clicked() {
|
||||
ui.output().copied_text = pkhex.0;
|
||||
}
|
||||
});
|
||||
|
||||
if let Ok(bech32) = pk.try_as_bech32_string() {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(&format!("Public Key (bech32): {}", bech32));
|
||||
if ui.add(CopyButton {}).clicked() {
|
||||
ui.output().copied_text = bech32;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ui.button("Delete this public key").clicked() {
|
||||
let _ = GLOBALS.to_overlord.send(BusMessage {
|
||||
target: "overlord".to_string(),
|
||||
kind: "delete_pub".to_string(),
|
||||
json_payload: serde_json::to_string(&app.import_pub).unwrap(),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label("Enter your public key");
|
||||
ui.add(TextEdit::singleline(&mut app.import_pub).hint_text("npub1 or hex"));
|
||||
if ui.button("Import a Public Key").clicked() {
|
||||
let _ = GLOBALS.to_overlord.send(BusMessage {
|
||||
target: "overlord".to_string(),
|
||||
kind: "import_pub".to_string(),
|
||||
json_payload: serde_json::to_string(&app.import_pub).unwrap(),
|
||||
});
|
||||
app.import_pub = "".to_owned();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user