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