use crate::screengrab::{self, Capture};
pub fn scan_screens_for_otpauth() -> Result<String, String> {
let captures = screengrab::capture_screens()?;
if captures.is_empty() {
return Err("no screens available to scan".into());
}
let mut found_any_qr = false;
let mut saw_hotp = false;
for capture in &captures {
let texts = match capture {
Capture::Rgba {
width,
height,
data,
} => keyroost_qr::texts_from_rgba(*width, *height, data),
Capture::Png(bytes) => keyroost_qr::texts_from_image(bytes),
};
let texts = match texts {
Ok(t) => t,
Err(_) => continue, };
for text in texts.iter() {
let trimmed = text.trim();
let lower = trimmed.to_ascii_lowercase();
if lower.starts_with("otpauth://totp/") {
return Ok(trimmed.to_string());
}
if lower.starts_with("otpauth://") {
found_any_qr = true;
if lower.starts_with("otpauth://hotp/") {
saw_hotp = true;
}
} else if !trimmed.is_empty() {
found_any_qr = true;
}
}
}
if saw_hotp {
Err("this is an HOTP code; only TOTP is supported".into())
} else if found_any_qr {
Err("a QR code was found, but it isn't a TOTP (otpauth://totp) code".into())
} else {
Err("no QR code found on screen — make sure the TOTP QR is visible".into())
}
}