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