authenticator/backup/
legacy.rs

1use anyhow::Result;
2use gettextrs::gettext;
3use serde::Deserialize;
4use zeroize::{Zeroize, ZeroizeOnDrop};
5
6use super::{Restorable, RestorableItem};
7use crate::models::{Algorithm, Method};
8
9// Same as andOTP except uses the first tag for the issuer
10#[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        // Translators: this is for restoring a backup from the old Authenticator
40        // release
41        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}