keyfork-prompt: split on word boundaries for textual prompts
This commit is contained in:
parent
df7be182e4
commit
f157a8c954
|
@ -9,6 +9,6 @@ pub fn main() -> Result<()> {
|
|||
let string = mgr.prompt_wordlist("Mnemonic: ", &Default::default())?;
|
||||
let mnemonic = Mnemonic::from_str(&string).unwrap();
|
||||
let entropy = mnemonic.entropy();
|
||||
mgr.prompt_message(&format!("Your entropy is: {entropy:X?}"))?;
|
||||
mgr.prompt_message(Message::Text(format!("Your entropy is: {entropy:X?}")))?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -31,6 +31,11 @@ pub enum Error {
|
|||
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
||||
pub enum Message {
|
||||
Text(String),
|
||||
Data(String),
|
||||
}
|
||||
|
||||
pub struct PromptManager<R, W> {
|
||||
read: BufReader<R>,
|
||||
write: W,
|
||||
|
@ -243,40 +248,59 @@ where
|
|||
Ok(passphrase)
|
||||
}
|
||||
|
||||
pub fn prompt_message(&mut self, prompt: &str) -> Result<()> {
|
||||
pub fn prompt_message(&mut self, prompt: Message) -> Result<()> {
|
||||
let mut terminal = AlternateScreen::new(&mut self.write)?;
|
||||
let mut terminal = RawMode::new(&mut terminal)?;
|
||||
|
||||
loop {
|
||||
// TODO: split on word boundaries
|
||||
let (cols, _) = terminal::size()?;
|
||||
|
||||
terminal
|
||||
.queue(terminal::Clear(terminal::ClearType::All))?
|
||||
.queue(cursor::MoveTo(0, 0))?;
|
||||
let mut lines = prompt.lines().peekable();
|
||||
while let Some(line) = lines.next() {
|
||||
terminal.queue(Print(line))?;
|
||||
if lines.peek().is_some() {
|
||||
|
||||
use Message::*;
|
||||
match &prompt {
|
||||
Text(text) => {
|
||||
for line in text.lines() {
|
||||
let mut written_chars = 0;
|
||||
for word in line.split_whitespace() {
|
||||
let len = word.len() as u16;
|
||||
written_chars += len + 1;
|
||||
if written_chars > cols {
|
||||
terminal
|
||||
.queue(cursor::MoveDown(1))?
|
||||
.queue(cursor::MoveToColumn(0))?;
|
||||
written_chars = len + 1;
|
||||
}
|
||||
terminal.queue(Print(word))?.queue(Print(" "))?;
|
||||
}
|
||||
terminal
|
||||
.queue(cursor::MoveDown(1))?
|
||||
.queue(cursor::MoveToColumn(0))?;
|
||||
}
|
||||
}
|
||||
Data(data) => {
|
||||
for line in data.lines() {
|
||||
terminal
|
||||
.queue(Print(line))?
|
||||
.queue(cursor::MoveDown(1))?
|
||||
.queue(cursor::MoveToColumn(0))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
terminal
|
||||
.queue(cursor::DisableBlinking)?
|
||||
.queue(cursor::MoveDown(1))?
|
||||
.queue(cursor::MoveToColumn(0))?
|
||||
.queue(PrintStyledContent(" OK ".negative()))?
|
||||
.flush()?;
|
||||
|
||||
match read()? {
|
||||
Event::Key(k) => match k.code {
|
||||
KeyCode::Enter | KeyCode::Char(' ') => break,
|
||||
KeyCode::Enter | KeyCode::Char(' ') | KeyCode::Char('q') => break,
|
||||
_ => (),
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
terminal.queue(cursor::EnableBlinking)?.flush()?;
|
||||
Ok(())
|
||||
|
|
|
@ -11,7 +11,7 @@ use aes_gcm::{aead::Aead, aes::cipher::consts::U12, Aes256Gcm, KeyInit, Nonce};
|
|||
use x25519_dalek::{EphemeralSecret, PublicKey};
|
||||
|
||||
use keyfork_mnemonic_util::{Mnemonic, Wordlist};
|
||||
use keyfork_prompt::PromptManager;
|
||||
use keyfork_prompt::{PromptManager, Message};
|
||||
use keyfork_shard::openpgp::{decrypt_one, discover_certs, openpgp::Cert, parse_messages};
|
||||
|
||||
type Result<T, E = Box<dyn std::error::Error>> = std::result::Result<T, E>;
|
||||
|
@ -85,7 +85,7 @@ fn run() -> Result<()> {
|
|||
let our_mnemonic =
|
||||
Mnemonic::from_entropy(PublicKey::from(&our_key).as_bytes(), Default::default())?;
|
||||
// TODO: Encode using `qrencode -t ansiutf8 -m 2`
|
||||
pm.prompt_message(&format!("Our words: {our_mnemonic}"))?;
|
||||
pm.prompt_message(Message::Text(format!("Our words: {our_mnemonic}")))?;
|
||||
|
||||
let shared_secret = our_key
|
||||
.diffie_hellman(&PublicKey::from(their_key))
|
||||
|
@ -109,7 +109,7 @@ fn run() -> Result<()> {
|
|||
// safety: size of out_bytes is constant and always % 4 == 0
|
||||
let mnemonic = unsafe { Mnemonic::from_raw_entropy(&out_bytes, Default::default()) };
|
||||
|
||||
pm.prompt_message(&format!("Our payload: {mnemonic}"))?;
|
||||
pm.prompt_message(Message::Text(format!("Our payload: {mnemonic}")))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use keyfork_prompt::{default_prompt_manager, DefaultPromptManager, Error as PromptError};
|
||||
use keyfork_prompt::{default_prompt_manager, DefaultPromptManager, Error as PromptError, Message};
|
||||
|
||||
use super::openpgp::{
|
||||
self,
|
||||
|
@ -146,7 +146,7 @@ impl SmartcardManager {
|
|||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
self.pm.prompt_message("Please plug in a smart card and press enter")?;
|
||||
self.pm.prompt_message(Message::Text("Please plug in a smart card and press enter".to_string()))?;
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
|
@ -246,7 +246,7 @@ impl DecryptionHelper for &mut SmartcardManager {
|
|||
pin.replace(temp_pin);
|
||||
}
|
||||
Err(CardError::CardStatus(StatusBytes::IncorrectParametersCommandDataField)) => {
|
||||
self.pm.prompt_message("Invalid PIN length entered.")?;
|
||||
self.pm.prompt_message(Message::Text("Invalid PIN length entered.".to_string()))?;
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue