smbcloud_cli/account/forgot/
mod.rs1use crate::cli::CommandResult;
2use anyhow::Result;
3use console::style;
4use dialoguer::{theme::ColorfulTheme, Input, Password};
5use reqwest::{Client, StatusCode};
6use serde::{Deserialize, Serialize};
7use smbcloud_model::forgot::{Args, Email, Param, UserUpdatePassword};
8use smbcloud_networking::{constants::PATH_USERS_PASSWORD, smb_base_url_builder};
9use smbcloud_utils::email_validation;
10use spinners::Spinner;
11
12pub async fn process_forgot() -> Result<CommandResult> {
13 println!("Provide your login credentials.");
14 let email = Input::<String>::with_theme(&ColorfulTheme::default())
15 .with_prompt("Email")
16 .validate_with(|email: &String| email_validation(email))
17 .interact()
18 .unwrap();
19 let mut spinner = Spinner::new(
20 spinners::Spinners::SimpleDotsScrolling,
21 style("Checking email...").green().bold().to_string(),
22 );
23
24 let params = Args {
25 user: Email { email },
26 };
27
28 let response = Client::new()
29 .post(build_smb_forgot_url())
30 .json(¶ms)
31 .send()
32 .await?;
33
34 match response.status() {
35 StatusCode::OK => {
36 spinner.stop_and_persist(
37 "✅",
38 "Check your email and input your code here.".to_owned(),
39 );
40 input_code().await
41 }
42 _ => Ok(CommandResult {
43 spinner,
44 symbol: "😩".to_owned(),
45 msg: "Something wrong when trying to reset email.".to_owned(),
46 }),
47 }
48}
49
50async fn input_code() -> Result<CommandResult> {
51 let security_code = Input::<String>::with_theme(&ColorfulTheme::default())
52 .with_prompt("Code")
53 .interact()
54 .unwrap();
55
56 Spinner::new(
57 spinners::Spinners::SimpleDotsScrolling,
58 style("Checking your code...").green().bold().to_string(),
59 )
60 .stop_and_persist("✅", "Great. Now input your new password.".to_owned());
61
62 let new_password = Password::with_theme(&ColorfulTheme::default())
63 .with_prompt("Password")
64 .validate_with(|input: &String| -> Result<(), &str> {
65 if input.len() >= 6 {
66 Ok(())
67 } else {
68 Err("Password must be at least 6 characters")
69 }
70 })
71 .with_confirmation("Confirm password", "Passwords do not match")
72 .interact()
73 .unwrap();
74 let password_confirmation = String::from(&new_password);
75
76 let params = Param {
78 user: UserUpdatePassword {
79 reset_password_token: security_code,
80 password: new_password,
81 password_confirmation,
82 },
83 };
84
85 let spinner = Spinner::new(
86 spinners::Spinners::SimpleDotsScrolling,
87 style("Updating your password...")
88 .green()
89 .bold()
90 .to_string(),
91 );
92
93 let response = Client::new()
94 .put(build_smb_forgot_url())
95 .json(¶ms)
96 .send()
97 .await?;
98
99 #[derive(Debug, Serialize, Deserialize)]
100 struct Response {
101 status: i32,
102 email: Option<String>,
103 }
104
105 match response.status() {
106 StatusCode::OK => Ok(CommandResult {
107 spinner,
108 symbol: "✅".to_owned(),
109 msg: "Your password has been updated. Login with your new password.".to_owned(),
110 }),
111 StatusCode::NOT_FOUND => Ok(CommandResult {
112 spinner,
113 symbol: "😩".to_owned(),
114 msg: "URL not found.".to_owned(),
115 }),
116 _ => Ok(CommandResult {
117 spinner,
118 symbol: "😩".to_owned(),
119 msg: "Something wrong when trying to reset email.".to_owned(),
120 }),
121 }
122}
123
124fn build_smb_forgot_url() -> String {
125 let mut url_builder = smb_base_url_builder();
126 url_builder.add_route(PATH_USERS_PASSWORD);
127 url_builder.build()
128}