webauthn_authenticator_rs/ui/
cli.rs1use crate::ui::*;
2#[cfg(feature = "qrcode")]
3use qrcode::{render::unicode::Dense1x2, QrCode};
4use std::io::{stderr, Write};
5
6#[derive(Debug)]
16pub struct Cli {}
17
18impl UiCallback for Cli {
19 fn request_pin(&self) -> Option<String> {
20 rpassword::prompt_password_stderr("Enter PIN: ").ok()
21 }
22
23 fn request_touch(&self) {
24 let mut stderr = stderr();
25 writeln!(stderr, "Touch the authenticator").ok();
26 }
27
28 fn processing(&self) {
29 let mut stderr = stderr();
30 writeln!(stderr, "Processing...").ok();
31 }
32
33 fn fingerprint_enrollment_feedback(
34 &self,
35 remaining_samples: u32,
36 feedback: Option<EnrollSampleStatus>,
37 ) {
38 let mut stderr = stderr();
39 writeln!(stderr, "Need {remaining_samples} more sample(s)").ok();
40 if let Some(feedback) = feedback {
41 writeln!(stderr, "Last impression was {feedback:?}").ok();
42 }
43 }
44
45 fn cable_qr_code(&self, request_type: CableRequestType, url: String) {
46 match request_type {
47 CableRequestType::DiscoverableMakeCredential | CableRequestType::MakeCredential => {
48 println!("Scan the QR code with your mobile device to create a new credential with caBLE:");
49 }
50 CableRequestType::GetAssertion => {
51 println!("Scan the QR code with your mobile device to sign in with caBLE:");
52 }
53 }
54 println!("This feature requires Android with Google Play, or iOS 16 or later.");
55
56 #[cfg(feature = "qrcode")]
57 {
58 let qr = QrCode::new(&url).expect("Could not create QR code");
59
60 let code = qr
61 .render::<Dense1x2>()
62 .dark_color(Dense1x2::Light)
63 .light_color(Dense1x2::Dark)
64 .build();
65
66 println!("{}", code);
67 }
68
69 #[cfg(not(feature = "qrcode"))]
70 {
71 println!("QR code support not available in this build!")
72 }
73 println!("{url}");
74 }
75
76 fn dismiss_qr_code(&self) {
77 println!("caBLE authenticator detected, connecting...");
78 }
79
80 fn cable_status_update(&self, state: CableState) {
81 println!("caBLE status: {state:?}");
82 }
83}