4 files changed
+103
-24
smbpndk-cli/src/account/lib.rs
+2
-2
@@ -174,7 +174,7 @@ pub async fn process_connect_github(code: String) -> Result<SmbAuthorization> {
174
StatusCode::OK => {
175
// Account authorized and token received
176
spinner.stop_and_persist("✅", "You're logged in with your GitHub account!".into());
177
- let result: SmbAuthorization = response.json().await?;
177
+ let result = response.json().await?;
178
println!("Result: {:#?}", &result);
179
Ok(result)
180
}
@@ -188,7 +188,7 @@ pub async fn process_connect_github(code: String) -> Result<SmbAuthorization> {
188
StatusCode::UNPROCESSABLE_ENTITY => {
189
// Account found but email not verified
190
spinner.stop_and_persist("🥹", "Unverified email!".into());
191
- let result: SmbAuthorization = response.json().await?;
191
+ let result = response.json().await?;
192
println!("Result: {:#?}", &result);
193
Ok(result)
194
}
smbpndk-cli/src/account/login/process.rs
+80
-16
@@ -12,7 +12,6 @@ use log::debug;
12
use reqwest::Client;
13
use serde::{Deserialize, Serialize};
14
use smbpndk_model::CommandResult;
15
-use smbpndk_networking::constants::BASE_URL;
15
use smbpndk_utils::email_validation;
16
use spinners::Spinner;
17
use std::{
@@ -27,7 +26,13 @@ pub struct LoginArgs {
26
27
#[derive(Debug, Serialize)]
28
struct LoginParams {
30
- user: User,
29
+ user: UserParam,
30
+}
31
+
32
+#[derive(Debug, Serialize)]
33
+struct UserParam {
34
+ email: String,
35
+ password: String,
36
}
37
38
#[derive(Debug, Serialize, Deserialize)]
@@ -62,8 +67,19 @@ async fn login_with_github() -> Result<CommandResult> {
67
}
68
69
async fn process_authorization(auth: SmbAuthorization) -> Result<CommandResult> {
70
+ // What to do if not logged in with GitHub?
71
+ // Check error_code first
72
+ if let Some(error_code) = auth.error_code {
73
+ debug!("{}", error_code);
74
+ match error_code {
75
+ ErrorCode::EmailNotFound => return create_new_account(auth.user_email, auth.user_info).await,
76
+ ErrorCode::EmailUnverified => return send_email_verification(auth.user).await,
77
+ }
78
+ }
79
+
80
// Logged in with GitHub
81
if let Some(user) = auth.user {
82
+ print!("You are logged in with GitHub as {}.", user);
83
let spinner = Spinner::new(
84
spinners::Spinners::SimpleDotsScrolling,
85
style("Logging you in...").green().bold().to_string(),
@@ -76,17 +92,6 @@ async fn process_authorization(auth: SmbAuthorization) -> Result<CommandResult>
92
});
93
}
94
79
- // What to do if not logged in with GitHub?
80
- if let Some(error_code) = auth.error_code {
81
- debug!("{}", error_code);
82
- match error_code {
83
- ErrorCode::EmailNotFound => {
84
- return create_new_account(auth.user_email, auth.user_info).await
85
- }
86
- ErrorCode::EmailUnverified => return send_email_verification(auth.user_email).await,
87
- }
88
- }
89
-
95
let error: anyhow::Error = anyhow!("Failed to login with GitHub.");
96
Err(error)
97
}
@@ -130,8 +135,61 @@ async fn create_new_account(
135
Err(anyhow!("Shouldn't be here."))
136
}
137
133
-async fn send_email_verification(user_email: Option<GithubEmail>) -> Result<CommandResult> {
134
- Err(anyhow!("Failed to send email verification."))
138
+async fn send_email_verification(user: Option<User>) -> Result<CommandResult> {
139
+ // Return early if user is null
140
+ if let Some(user) = user {
141
+
142
+ let confirm = Confirm::with_theme(&ColorfulTheme::default())
143
+ .with_prompt("Do you want to send a new verification email?")
144
+ .interact()
145
+ .unwrap();
146
+
147
+ // Send verification email if user confirms
148
+ if !confirm {
149
+ let spinner = Spinner::new(
150
+ spinners::Spinners::SimpleDotsScrolling,
151
+ style("Cancel operation.").green().bold().to_string(),
152
+ );
153
+ return Ok(CommandResult {
154
+ spinner,
155
+ symbol: "✅".to_owned(),
156
+ msg: "Doing nothing.".to_owned(),
157
+ });
158
+ }
159
+ resend_email_verification(user).await
160
+ } else {
161
+ let error = anyhow!("Failed to get user.");
162
+ Err(error)
163
+ }
164
+}
165
+
166
+async fn resend_email_verification(user: User) -> Result<CommandResult> {
167
+ let spinner = Spinner::new(
168
+ spinners::Spinners::SimpleDotsScrolling,
169
+ style("Sending verification email...").green().bold().to_string(),
170
+ );
171
+
172
+ let response = Client::new()
173
+ .post(build_smb_resend_email_verification_url())
174
+ .body(format!("id={}", user.id))
175
+ .header("Accept", "application/json")
176
+ .header("Content-Type", "application/x-www-form-urlencoded")
177
+ .send()
178
+ .await?;
179
+
180
+ match response.status() {
181
+ reqwest::StatusCode::OK => {
182
+ Ok(CommandResult {
183
+ spinner,
184
+ symbol: "✅".to_owned(),
185
+ msg: "Verification email sent!".to_owned(),
186
+ })
187
+ }
188
+ _ => {
189
+ let error = anyhow!("Failed to send verification email.");
190
+ Err(error)
191
+ }
192
+ }
193
}
194
195
async fn login_with_email() -> Result<CommandResult> {
@@ -167,7 +225,7 @@ async fn login_with_email() -> Result<CommandResult> {
225
226
async fn do_process_login(args: LoginArgs) -> Result<()> {
227
let login_params = LoginParams {
170
- user: User {
228
+ user: UserParam {
229
email: args.username,
230
password: args.password,
231
},
@@ -222,6 +280,12 @@ fn build_smb_login_url() -> String {
280
url_builder.build()
281
}
282
283
+fn build_smb_resend_email_verification_url() -> String {
284
+ let mut url_builder = smb_base_url_builder();
285
+ url_builder.add_route("v1/resend_confirmation");
286
+ url_builder.build()
287
+}
288
+
289
pub async fn process_logout() -> Result<CommandResult> {
290
let spinner = Spinner::new(
291
spinners::Spinners::SimpleDotsScrolling,
smbpndk-cli/src/account/model/mod.rs
+10
-1
@@ -1,9 +1,18 @@
1
+use std::fmt::{Formatter, Display};
2
+
3
use serde::{Deserialize, Serialize};
4
5
+// SMBPNDK Users.
6
#[derive(Debug, Serialize, Deserialize)]
7
pub struct User {
8
+ pub(crate) id: i32,
9
pub(crate) email: String,
6
- pub(crate) password: String,
10
+}
11
+
12
+impl Display for User {
13
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
14
+ write!(f, "User: id: {}, email: {}", self.id, self.email)
15
+ }
16
}
17
18
#[derive(Debug, Serialize, Deserialize)]
smbpndk-cli/src/account/signup/process.rs
+11
-5
@@ -1,6 +1,6 @@
1
use super::SignupMethod;
2
use crate::account::{
3
- lib::authorize_github,
3
+ lib::{authorize_github, smb_base_url_builder},
4
model::{Data, Status},
5
};
6
use anyhow::{anyhow, Result};
@@ -10,7 +10,7 @@ use log::debug;
10
use reqwest::{Client, StatusCode};
11
use serde::{Deserialize, Serialize};
12
use smbpndk_model::CommandResult;
13
-use smbpndk_networking::constants::BASE_URL;
13
+
14
use smbpndk_utils::email_validation;
15
use spinners::Spinner;
16
use std::fmt::{Display, Formatter};
@@ -168,7 +168,7 @@ pub async fn do_signup<T: Serialize + ?Sized>(args: &T) -> Result<CommandResult>
168
);
169
170
let response = Client::new()
171
- .post([BASE_URL, "/v1/users"].join(""))
171
+ .post(build_smb_signup_url())
172
.json(&args)
173
.send()
174
.await?;
@@ -176,8 +176,8 @@ pub async fn do_signup<T: Serialize + ?Sized>(args: &T) -> Result<CommandResult>
176
match response.status() {
177
StatusCode::OK => Ok(CommandResult {
178
spinner,
179
- symbol: "Yes".to_owned(),
180
- msg: "Success. Check email".to_owned(),
179
+ symbol: "✅".to_owned(),
180
+ msg: "Your account has been created. Check email for verification link.".to_owned(),
181
}),
182
StatusCode::UNPROCESSABLE_ENTITY => {
183
let result: SignupResult = response.json().await?;
@@ -190,3 +190,9 @@ pub async fn do_signup<T: Serialize + ?Sized>(args: &T) -> Result<CommandResult>
190
}
191
}
192
}
193
+
194
+fn build_smb_signup_url() -> String {
195
+ let mut url_builder = smb_base_url_builder();
196
+ url_builder.add_route("v1/users");
197
+ url_builder.build()
198
+}