12 files changed
+125
-58
crates/cli/src/account/login/process.rs
+2
-1
@@ -33,7 +33,7 @@ use {
33
},
34
smb_base_url_builder,
35
},
36
- smbcloud_networking_account::{login::login, signup::check_email},
36
+ smbcloud_networking_account::{check_email::check_email, login::login},
37
smbcloud_utils::email_validation,
38
spinners::Spinner,
39
};
@@ -300,6 +300,7 @@ async fn login_with_email(env: Environment) -> Result<CommandResult> {
300
return Err(error);
301
}
302
};
303
+
304
match check_email(env, &username).await {
305
Ok(auth) => {
306
// Only continue with password input if email is found and confirmed.
crates/cli/src/account/logout/mod.rs
+5
-11
@@ -6,10 +6,8 @@ use {
6
},
7
anyhow::{anyhow, Result},
8
dialoguer::{theme::ColorfulTheme, Confirm},
9
- reqwest::{Client, StatusCode},
9
smbcloud_network::environment::Environment,
11
- smbcloud_networking::{constants::PATH_USERS_SIGN_OUT, smb_base_url_builder},
12
- smbcloud_networking_account::logout::{self, logout},
10
+ smbcloud_networking_account::logout::logout,
11
spinners::Spinner,
12
std::fs,
13
};
@@ -69,12 +67,8 @@ pub async fn process_logout(env: Environment) -> Result<CommandResult> {
67
68
async fn do_process_logout(env: Environment) -> Result<()> {
69
let token = get_smb_token(env)?;
72
-
73
- logout(env, token).await?
74
-}
75
-
76
-fn build_smb_logout_url(env: Environment) -> String {
77
- let mut url_builder = smb_base_url_builder(env);
78
- url_builder.add_route(PATH_USERS_SIGN_OUT);
79
- url_builder.build()
70
+ match logout(env, token).await {
71
+ Ok(_) => Ok(()),
72
+ Err(e) => Err(anyhow!("{e}")),
73
+ }
74
}
crates/cli/src/account/signup/process.rs
+48
-21
@@ -1,20 +1,26 @@
1
-use super::SignupMethod;
2
-use crate::token::smb_token_file_path::smb_token_file_path;
3
-use crate::{
4
- account::lib::authorize_github,
5
- cli::CommandResult,
6
- ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
1
+use {
2
+ super::SignupMethod,
3
+ crate::{
4
+ account::lib::authorize_github,
5
+ cli::CommandResult,
6
+ token::smb_token_file_path::smb_token_file_path,
7
+ ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
8
+ },
9
+ anyhow::{anyhow, Result},
10
+ dialoguer::{console::Term, theme::ColorfulTheme, Input, Password, Select},
11
+ log::debug,
12
+ reqwest::{Client, StatusCode},
13
+ serde::Serialize,
14
+ smbcloud_model::signup::SignupResult,
15
+ smbcloud_network::environment::Environment,
16
+ smbcloud_networking::{
17
+ constants::{PATH_USERS, SMB_USER_AGENT},
18
+ smb_base_url_builder,
19
+ },
20
+ smbcloud_networking_account::signup::signup,
21
+ smbcloud_utils::email_validation,
22
+ spinners::Spinner,
23
};
8
-use anyhow::{anyhow, Result};
9
-use dialoguer::{console::Term, theme::ColorfulTheme, Input, Password, Select};
10
-use log::debug;
11
-use reqwest::{Client, StatusCode};
12
-use serde::Serialize;
13
-use smbcloud_model::signup::{SignupEmailParams, SignupResult, SignupUserEmail};
14
-use smbcloud_network::environment::Environment;
15
-use smbcloud_networking::{constants::PATH_USERS, smb_base_url_builder};
16
-use smbcloud_utils::email_validation;
17
-use spinners::Spinner;
24
25
pub async fn process_signup(env: Environment) -> Result<CommandResult> {
26
// Check if token file exists
@@ -75,11 +81,7 @@ async fn signup_input_password_step(env: Environment, email: String) -> Result<C
81
succeed_message("Signing up"),
82
);
83
78
- let params = SignupEmailParams {
79
- user: SignupUserEmail { email, password },
80
- };
81
-
82
- match do_signup(env, ¶ms).await {
84
+ match do_signup_email(env, email, password).await {
85
Ok(_) => Ok(CommandResult {
86
spinner,
87
symbol: succeed_symbol(),
@@ -150,3 +152,28 @@ fn build_smb_signup_url(env: Environment) -> String {
152
url_builder.add_route(PATH_USERS);
153
url_builder.build()
154
}
155
+
156
+pub async fn do_signup_email(
157
+ env: Environment,
158
+ email: String,
159
+ password: String,
160
+) -> Result<CommandResult> {
161
+ let spinner = Spinner::new(
162
+ spinners::Spinners::BouncingBall,
163
+ succeed_message("Signing you up"),
164
+ );
165
+
166
+ match signup(env, SMB_USER_AGENT.to_string(), email, password).await {
167
+ Ok(_) => Ok(CommandResult {
168
+ spinner,
169
+ symbol: succeed_symbol(),
170
+ msg: succeed_message(
171
+ "Your account has been created. Check email for verification link.",
172
+ ),
173
+ }),
174
+ Err(e) => {
175
+ let error = anyhow!("Failed to signup: {}", e);
176
+ Err(error)
177
+ }
178
+ }
179
+}
crates/smbcloud-model/src/account.rs
+2
@@ -30,6 +30,7 @@ pub struct Status {
30
}
31
32
#[derive(Debug, Serialize, Deserialize)]
33
+#[tsync]
34
pub struct Data {
35
id: i32,
36
email: String,
@@ -49,6 +50,7 @@ pub struct SmbAuthorization {
50
51
#[derive(Debug, Serialize_repr, Deserialize_repr, PartialEq)]
52
#[repr(u32)]
53
+#[tsync]
54
pub enum ErrorCode {
55
EmailNotFound = 1000,
56
EmailUnverified = 1001,
crates/smbcloud-model/src/login.rs
+2
@@ -1,6 +1,7 @@
1
use {
2
crate::account::{Data, ErrorCode, Status},
3
serde::{Deserialize, Serialize},
4
+ tsync::tsync,
5
};
6
7
#[derive(Debug, Serialize)]
@@ -28,6 +29,7 @@ pub struct LoginResult {
29
30
/// Login endpoint result.
31
#[derive(Debug, Serialize, Deserialize)]
32
+#[tsync]
33
pub enum AccountStatus {
34
NotFound,
35
Ready { access_token: String },
crates/smbcloud-model/src/project.rs
+9
-6
@@ -1,9 +1,11 @@
1
-use std::fmt::Display;
2
-
3
-use crate::{app_auth::AuthApp, ar_date_format};
4
-use chrono::{DateTime, Utc};
5
-use serde::{Deserialize, Serialize};
6
-use serde_repr::{Deserialize_repr, Serialize_repr};
1
+use {
2
+ crate::{app_auth::AuthApp, ar_date_format},
3
+ chrono::{DateTime, Utc},
4
+ serde::{Deserialize, Serialize},
5
+ serde_repr::{Deserialize_repr, Serialize_repr},
6
+ std::fmt::Display,
7
+ tsync::tsync,
8
+};
9
10
#[derive(Deserialize, Debug, Serialize)]
11
pub struct Config {
@@ -12,6 +14,7 @@ pub struct Config {
14
}
15
16
#[derive(Deserialize, Serialize, Debug, Clone)]
17
+#[tsync]
18
pub struct Project {
19
pub id: i32,
20
pub name: String,
crates/smbcloud-model/src/signup.rs
+7
-3
@@ -1,6 +1,9 @@
1
-use crate::account::{Data, Status};
2
-use serde::{Deserialize, Serialize};
3
-use std::fmt::{Display, Formatter};
1
+use {
2
+ crate::account::{Data, Status},
3
+ serde::{Deserialize, Serialize},
4
+ std::fmt::{Display, Formatter},
5
+ tsync::tsync,
6
+};
7
8
pub struct SignupArgs {
9
pub email: String,
@@ -38,6 +41,7 @@ pub struct SignupUserEmail {
41
}
42
43
#[derive(Debug, Serialize, Deserialize)]
44
+#[tsync]
45
pub struct SignupResult {
46
pub status: Status,
47
pub data: Option<Data>,
crates/smbcloud-networking-account/src/check_email.rs
new
+21
@@ -0,0 +1,21 @@
1
+use {
2
+ reqwest::Client,
3
+ smbcloud_model::{account::SmbAuthorization, error_codes::ErrorResponse},
4
+ smbcloud_network::{environment::Environment, network::request},
5
+ smbcloud_networking::{constants::PATH_USERS_CHECK_EMAIL, smb_base_url_builder},
6
+};
7
+
8
+pub async fn check_email(env: Environment, email: &str) -> Result<SmbAuthorization, ErrorResponse> {
9
+ let builder = Client::new()
10
+ .get(build_url(env, email))
11
+ .header("Accept", "application/json")
12
+ .header("Content-Type", "application/x-www-form-urlencoded");
13
+ request(builder).await
14
+}
15
+
16
+fn build_url(env: Environment, email: &str) -> String {
17
+ let mut url_builder = smb_base_url_builder(env);
18
+ url_builder.add_route(PATH_USERS_CHECK_EMAIL);
19
+ url_builder.add_param("email", email);
20
+ url_builder.build()
21
+}
crates/smbcloud-networking-account/src/lib.rs
+1
@@ -1,3 +1,4 @@
1
+pub mod check_email;
2
pub mod login;
3
pub mod logout;
4
pub mod me;
crates/smbcloud-networking-account/src/signup.rs
+19
-9
@@ -1,21 +1,31 @@
1
use {
2
reqwest::Client,
3
- smbcloud_model::{account::SmbAuthorization, error_codes::ErrorResponse},
3
+ smbcloud_model::{
4
+ error_codes::ErrorResponse,
5
+ signup::{SignupEmailParams, SignupResult, SignupUserEmail},
6
+ },
7
smbcloud_network::{environment::Environment, network::request},
5
- smbcloud_networking::{constants::PATH_USERS_CHECK_EMAIL, smb_base_url_builder},
8
+ smbcloud_networking::{constants::PATH_USERS, smb_base_url_builder},
9
};
10
8
-pub async fn check_email(env: Environment, email: &str) -> Result<SmbAuthorization, ErrorResponse> {
11
+pub async fn signup(
12
+ env: Environment,
13
+ user_agent: String,
14
+ email: String,
15
+ password: String,
16
+) -> Result<SignupResult, ErrorResponse> {
17
+ let params = SignupEmailParams {
18
+ user: SignupUserEmail { email, password },
19
+ };
20
let builder = Client::new()
10
- .get(build_url(env, email))
11
- .header("Accept", "application/json")
12
- .header("Content-Type", "application/x-www-form-urlencoded");
21
+ .post(build_smb_signup_url(env))
22
+ .json(¶ms)
23
+ .header("User-agent", user_agent);
24
request(builder).await
25
}
26
16
-fn build_url(env: Environment, email: &str) -> String {
27
+fn build_smb_signup_url(env: Environment) -> String {
28
let mut url_builder = smb_base_url_builder(env);
18
- url_builder.add_route(PATH_USERS_CHECK_EMAIL);
19
- url_builder.add_param("email", email);
29
+ url_builder.add_route(PATH_USERS);
30
url_builder.build()
31
}
crates/smbcloud-networking-project/src/crud_project_read.rs
+7
-5
@@ -1,8 +1,10 @@
1
-use crate::url_builder::{build_project_url, build_project_url_with_id};
2
-use reqwest::Client;
3
-use smbcloud_model::{error_codes::ErrorResponse, project::Project};
4
-use smbcloud_network::{environment::Environment, network::request};
5
-use smbcloud_networking::constants::SMB_USER_AGENT;
1
+use {
2
+ crate::url_builder::{build_project_url, build_project_url_with_id},
3
+ reqwest::Client,
4
+ smbcloud_model::{error_codes::ErrorResponse, project::Project},
5
+ smbcloud_network::{environment::Environment, network::request},
6
+ smbcloud_networking::constants::SMB_USER_AGENT,
7
+};
8
9
pub async fn get_project(
10
env: Environment,
crates/smbcloud-networking/src/constants.rs
+2
-2
@@ -7,8 +7,8 @@ pub const GH_OAUTH_REDIRECT_HOST: &str = "http://localhost";
7
pub const GH_OAUTH_REDIRECT_PORT: &str = "8808";
8
9
pub const SMB_CLIENT_ID: &str = "cli";
10
-pub const SMB_CLIENT_SECRET: &str = "secretttttttt";
11
-pub const SMB_USER_AGENT: &str = "smbcloud-cli";
10
+pub const SMB_CLIENT_SECRET: &str = "YOUR_SMB_CLIENT_SECRET";
11
+pub const SMB_USER_AGENT: &str = "YOUR_SMB_USER_AGENT";
12
13
// Paths
14
pub const PATH_USERS_CHECK_EMAIL: &str = "v1/check_email";