authenticator/backup/
legacy.rs1use anyhow::Result;
2use gettextrs::gettext;
3use serde::Deserialize;
4use zeroize::{Zeroize, ZeroizeOnDrop};
5
6use super::{Restorable, RestorableItem};
7use crate::models::{Algorithm, Method};
8
9#[derive(Deserialize, Zeroize, ZeroizeOnDrop)]
11pub struct LegacyAuthenticator {
12 pub secret: String,
13 #[zeroize(skip)]
14 pub label: String,
15 #[zeroize(skip)]
16 pub digits: u32,
17 #[serde(rename = "type")]
18 #[zeroize(skip)]
19 pub method: Method,
20 #[zeroize(skip)]
21 pub algorithm: Algorithm,
22 #[zeroize(skip)]
23 pub thumbnail: String,
24 #[zeroize(skip)]
25 pub last_used: i64,
26 #[zeroize(skip)]
27 pub tags: Vec<String>,
28 #[zeroize(skip)]
29 pub period: u32,
30}
31
32impl Restorable for LegacyAuthenticator {
33 const ENCRYPTABLE: bool = false;
34 const SCANNABLE: bool = false;
35 const IDENTIFIER: &'static str = "authenticator_legacy";
36 type Item = Self;
37
38 fn title() -> String {
39 gettext("Au_thenticator (Legacy)")
42 }
43
44 fn subtitle() -> String {
45 gettext("From a plain-text JSON file")
46 }
47
48 fn restore_from_data(from: &[u8], _key: Option<&str>) -> Result<Vec<Self::Item>> {
49 serde_json::de::from_slice(from).map_err(From::from)
50 }
51}
52
53impl RestorableItem for LegacyAuthenticator {
54 fn account(&self) -> String {
55 self.label.clone()
56 }
57
58 fn issuer(&self) -> String {
59 self.tags
60 .first()
61 .cloned()
62 .unwrap_or_else(|| "Default".to_string())
63 }
64
65 fn secret(&self) -> String {
66 self.secret.clone()
67 }
68
69 fn period(&self) -> Option<u32> {
70 Some(self.period)
71 }
72
73 fn method(&self) -> Method {
74 self.method
75 }
76
77 fn algorithm(&self) -> Algorithm {
78 self.algorithm
79 }
80
81 fn digits(&self) -> Option<u32> {
82 Some(self.digits)
83 }
84
85 fn counter(&self) -> Option<u32> {
86 None
87 }
88}