@smbcloud / cli / commits / 72240fa

send reset password

Seto Elkahfi committed Sep 10, 2023 at 12:07 UTC 72240fae305b1468f598f759fed9110e0573d22b
1 file changed +93 -40
smbpndk-cli/src/account/login/process.rs
+93 -40
@@ -9,7 +9,7 @@ use anyhow::{anyhow, Result};
9 use console::{style, Term};
10 use dialoguer::{theme::ColorfulTheme, Confirm, Input, Password, Select};
11 use log::debug;
12 -use reqwest::{Client, StatusCode};
12 +use reqwest::{Client, StatusCode, Response};
13 use serde::{Deserialize, Serialize};
14 use smbpndk_model::CommandResult;
15 use smbpndk_utils::email_validation;
@@ -86,7 +86,7 @@ async fn process_authorization(auth: SmbAuthorization) -> Result<CommandResult>
86
87 // Logged in with GitHub
88 if let Some(user) = auth.user {
89 - print!("You are logged in with GitHub as {}.", user);
89 + println!("You are logged in with GitHub as {}.", user);
90 let spinner = Spinner::new(
91 spinners::Spinners::SimpleDotsScrolling,
92 style("Logging you in...").green().bold().to_string(),
@@ -229,40 +229,8 @@ async fn do_process_login(args: LoginArgs) -> Result<CommandResult> {
229
230 match response.status() {
231 StatusCode::OK => {
232 - let headers = response.headers();
233 - match headers.get("Authorization") {
234 - Some(token) => {
235 - debug!("{}", token.to_str()?);
236 - match home::home_dir() {
237 - Some(path) => {
238 - debug!("{}", path.to_str().unwrap());
239 - create_dir_all(path.join(".smb"))?;
240 - let mut file = OpenOptions::new()
241 - .create(true)
242 - .write(true)
243 - .open([path.to_str().unwrap(), "/.smb/token"].join(""))?;
244 - file.write_all(token.to_str()?.as_bytes())?;
245 -
246 - Ok(CommandResult {
247 - spinner: Spinner::new(
248 - spinners::Spinners::SimpleDotsScrolling,
249 - style("Logging you in...").green().bold().to_string(),
250 - ),
251 - symbol: "✅".to_owned(),
252 - msg: "You are logged in!".to_owned(),
253 - })
254 - }
255 - None => {
256 - let error = anyhow!("Failed to get home directory.");
257 - return Err(error);
258 - }
259 - }
260 - }
261 - None => {
262 - let error = anyhow!("Failed to get token. Probably a backend issue.");
263 - return Err(error);
264 - }
265 - }
232 + // Login successful
233 + save_token(response).await
234 }
235 StatusCode::NOT_FOUND => {
236 // Account not found and we show signup option
@@ -288,6 +256,43 @@ async fn do_process_login(args: LoginArgs) -> Result<CommandResult> {
256 }
257 }
258
259 +async fn save_token(response: Response) -> Result<CommandResult> {
260 + let headers = response.headers();
261 + match headers.get("Authorization") {
262 + Some(token) => {
263 + debug!("{}", token.to_str()?);
264 + match home::home_dir() {
265 + Some(path) => {
266 + debug!("{}", path.to_str().unwrap());
267 + create_dir_all(path.join(".smb"))?;
268 + let mut file = OpenOptions::new()
269 + .create(true)
270 + .write(true)
271 + .open([path.to_str().unwrap(), "/.smb/token"].join(""))?;
272 + file.write_all(token.to_str()?.as_bytes())?;
273 +
274 + Ok(CommandResult {
275 + spinner: Spinner::new(
276 + spinners::Spinners::SimpleDotsScrolling,
277 + style("Logging you in...").green().bold().to_string(),
278 + ),
279 + symbol: "✅".to_owned(),
280 + msg: "You are logged in!".to_owned(),
281 + })
282 + }
283 + None => {
284 + let error = anyhow!("Failed to get home directory.");
285 + return Err(error);
286 + }
287 + }
288 + }
289 + None => {
290 + let error = anyhow!("Failed to get token. Probably a backend issue.");
291 + return Err(error);
292 + }
293 + }
294 +}
295 +
296 async fn verify_or_set_password(result: SmbAuthorization) -> Result<CommandResult> {
297 match result.error_code {
298 Some(error_code) => {
@@ -336,7 +341,7 @@ async fn send_reset_password(user: Option<User>) -> Result<CommandResult> {
341 }
342
343 async fn resend_reset_password_instruction(user: User) -> Result<CommandResult> {
339 - let spinner = Spinner::new(
344 + let mut spinner = Spinner::new(
345 spinners::Spinners::SimpleDotsScrolling,
346 style("Sending reset password instruction...")
347 .green()
@@ -352,13 +357,55 @@ async fn resend_reset_password_instruction(user: User) -> Result<CommandResult>
357 .await?;
358
359 match response.status() {
355 - reqwest::StatusCode::OK => Ok(CommandResult {
360 + StatusCode::OK => {
361 + spinner.stop_and_persist("✅", "Reset password instruction sent! Please check your email.".to_owned());
362 + input_reset_password_token().await
363 + }
364 + _ => {
365 + let error = anyhow!("Failed to send reset password instruction.");
366 + Err(error)
367 + }
368 + }
369 +}
370 +
371 +async fn input_reset_password_token() -> Result<CommandResult> {
372 + let token = Input::<String>::with_theme(&ColorfulTheme::default())
373 + .with_prompt("Input reset password token")
374 + .interact()
375 + .unwrap();
376 + let password = Password::with_theme(&ColorfulTheme::default())
377 + .with_prompt("New password.")
378 + .with_confirmation("Repeat password.", "Error: the passwords don't match.")
379 + .interact()
380 + .unwrap();
381 +
382 + let spinner = Spinner::new(
383 + spinners::Spinners::SimpleDotsScrolling,
384 + style("Resetting password...")
385 + .green()
386 + .bold()
387 + .to_string(),
388 + );
389 +
390 + let response = Client::new()
391 + .put(build_smb_reset_password_url())
392 + .body(format!(
393 + "reset_password_token={}&password={}",
394 + token, password
395 + ))
396 + .header("Accept", "application/json")
397 + .header("Content-Type", "application/x-www-form-urlencoded")
398 + .send()
399 + .await?;
400 +
401 + match response.status() {
402 + StatusCode::OK => Ok(CommandResult {
403 spinner,
404 symbol: "✅".to_owned(),
358 - msg: "Reset password instruction sent!".to_owned(),
405 + msg: "Password reset!".to_owned(),
406 }),
407 _ => {
361 - let error = anyhow!("Failed to send reset password instruction.");
408 + let error = anyhow!("Failed to reset password.");
409 Err(error)
410 }
411 }
@@ -382,6 +429,12 @@ fn build_smb_resend_reset_password_instructions_url() -> String {
429 url_builder.build()
430 }
431
432 +fn build_smb_reset_password_url() -> String {
433 + let mut url_builder = smb_base_url_builder();
434 + url_builder.add_route("v1/users/password");
435 + url_builder.build()
436 +}
437 +
438 pub async fn process_logout() -> Result<CommandResult> {
439 let spinner = Spinner::new(
440 spinners::Spinners::SimpleDotsScrolling,