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