1pub use error::*;
2pub use database::join_paths;
3use std::collections::HashMap;
4
5mod database;
6pub mod error;
7pub mod otp;
8
9pub async fn init(folder: String) {
10 database::init(folder).await;
11}
12
13pub async fn print_codes() -> Vec<PrintCode> {
14 let mut codes: Vec<PrintCode> = Vec::new();
15 let registered_codes = database::registered::find_all().await;
16 for x in registered_codes {
17 let label = x.label;
18 let uuid = x.uuid;
19 match otp::totp(x.secret.as_str(), 30, 6) {
20 Ok(code) => {
21 codes.push(PrintCode { uuid, label, code });
22 }
23 Err(err) => {
24 codes.push(PrintCode {
25 uuid,
26 label,
27 code: match err {
28 Error::Hmac(_) => "HMac key error".to_owned(),
29 Error::Message(msg) => msg.content,
30 Error::Other(_) => "Exception".to_owned(),
31 },
32 });
33 }
34 };
35 }
36 codes
37}
38
39pub async fn save_url(url: String) -> Result<PrintCode> {
40 let url = match url::Url::parse(url.as_str()) {
41 Ok(url) => url,
42 Err(err) => {
43 return Err(Error::message(format!("Invalid url : {}", err)));
44 }
45 };
46 let path_split = url.path().split("/");
47 let label = path_split.last().expect("").to_owned();
48 let mut query_map: HashMap<String, String> = HashMap::new();
49 for (key, value) in url.query_pairs() {
50 query_map.insert(key.to_string(), value.to_string());
51 }
52 let secret = query_map
53 .get::<String>(&("secret".to_string()))
54 .expect("secret not found")
55 .to_string();
56 let issuer = match query_map.get::<String>(&("issuer".to_string())) {
57 None => "".to_string(),
58 Some(so) => so.to_string(),
59 };
60 Ok(save_register(label, secret, issuer).await?)
61}
62
63pub async fn save_register(label: String, secret: String, issuer: String) -> Result<PrintCode> {
64 let code = match otp::totp(secret.as_str(), 30, 6) {
65 Ok(code) => code,
66 Err(err) => {
67 return Err(err);
68 }
69 };
70 let registered = database::registered::Model {
71 uuid: uuid::Uuid::new_v4().to_string(),
72 label: label.clone(),
73 secret,
74 issuer,
75 };
76 database::registered::insert(registered.clone()).await;
77 Ok(PrintCode {
78 uuid: registered.uuid,
79 label: registered.label,
80 code,
81 })
82}
83
84pub async fn remove(uuid: &str) {
85 database::registered::delete_by_uuid(uuid).await;
86}
87
88pub async fn rename(uuid: &str, label: &str) {
89 database::registered::update_label_by_uuid(uuid, label).await;
90}
91
92pub struct PrintCode {
93 pub uuid: String,
94 pub label: String,
95 pub code: String,
96}