Implemented Changing Emails
This commit is contained in:
@@ -39,6 +39,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
id SERIAL,
|
id SERIAL,
|
||||||
username VARCHAR(255) NOT NULL,
|
username VARCHAR(255) NOT NULL,
|
||||||
email VARCHAR(255) NOT NULL,
|
email VARCHAR(255) NOT NULL,
|
||||||
|
new_email VARCHAR(255),
|
||||||
avatar TEXT NOT NULL,
|
avatar TEXT NOT NULL,
|
||||||
login_code INT(6),
|
login_code INT(6),
|
||||||
tokens TEXT,
|
tokens TEXT,
|
||||||
|
|||||||
@@ -122,6 +122,22 @@ impl RealmAuthServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn is_login_code_valid(&self, username: &str, login_code: u16) -> Result<bool, ErrorCode> {
|
||||||
|
let result = sqlx::query("SELECT login_code FROM user WHERE username = ?;")
|
||||||
|
.bind(username)
|
||||||
|
.fetch_one(&self.db_pool).await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(row) => {
|
||||||
|
if row.try_get::<u16, _>("login_code").unwrap() != login_code {
|
||||||
|
return Ok(false)
|
||||||
|
}
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
Err(_) => Err(InvalidUsername)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealmAuth for RealmAuthServer {
|
impl RealmAuth for RealmAuthServer {
|
||||||
@@ -236,17 +252,8 @@ impl RealmAuth for RealmAuthServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn finish_login_flow(self, _: Context, username: String, login_code: u16) -> Result<String, ErrorCode> {
|
async fn finish_login_flow(self, _: Context, username: String, login_code: u16) -> Result<String, ErrorCode> {
|
||||||
let result = sqlx::query("SELECT login_code FROM user WHERE username = ?;")
|
if !self.is_login_code_valid(&username, login_code).await? {
|
||||||
.bind(&username)
|
return Err(InvalidLoginCode)
|
||||||
.fetch_one(&self.db_pool).await;
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok(row) => {
|
|
||||||
if row.try_get::<u16, _>("login_code").unwrap() != login_code {
|
|
||||||
return Err(InvalidLoginCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => return Err(InvalidUsername)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = sqlx::query("UPDATE user SET login_code = NULL WHERE username = ?").bind(&username).execute(&self.db_pool).await;
|
let _ = sqlx::query("UPDATE user SET login_code = NULL WHERE username = ?").bind(&username).execute(&self.db_pool).await;
|
||||||
@@ -261,7 +268,10 @@ impl RealmAuth for RealmAuthServer {
|
|||||||
let mut tokens = token_long.split(',').collect::<Vec<&str>>();
|
let mut tokens = token_long.split(',').collect::<Vec<&str>>();
|
||||||
tokens.push(&token);
|
tokens.push(&token);
|
||||||
|
|
||||||
let result = sqlx::query("UPDATE user SET tokens = ? WHERE username = ?").bind(tokens.join(",")).bind(&username).execute(&self.db_pool).await;
|
let result = sqlx::query("UPDATE user SET tokens = ? WHERE username = ?")
|
||||||
|
.bind(tokens.join(",")) // TODO: This doesn't seem right and may cause problems
|
||||||
|
.bind(&username)
|
||||||
|
.execute(&self.db_pool).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => Ok(token),
|
Ok(_) => Ok(token),
|
||||||
Err(_) => Err(InvalidUsername)
|
Err(_) => Err(InvalidUsername)
|
||||||
@@ -272,11 +282,83 @@ impl RealmAuth for RealmAuthServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn change_email_flow(self, _: Context, username: String, new_email: String, token: String) -> ErrorCode {
|
async fn change_email_flow(self, _: Context, username: String, new_email: String, token: String) -> ErrorCode {
|
||||||
todo!()
|
let result = self.is_authorized(&username, &token).await;
|
||||||
|
match result {
|
||||||
|
Ok(authorized) => {
|
||||||
|
if !authorized {
|
||||||
|
return Unauthorized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(error) => return error
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = self.is_email_taken(&new_email).await;
|
||||||
|
match result {
|
||||||
|
Ok(taken) => {
|
||||||
|
if taken {
|
||||||
|
return EmailTaken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(error) => return error
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = sqlx::query("UPDATE user SET new_email = ? WHERE username = ?")
|
||||||
|
.bind(&new_email)
|
||||||
|
.bind(&username)
|
||||||
|
.execute(&self.db_pool).await;
|
||||||
|
match result {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(_) => return InvalidUsername
|
||||||
|
}
|
||||||
|
|
||||||
|
let code = self.gen_login_code();
|
||||||
|
|
||||||
|
let result = sqlx::query("UPDATE user SET login_code = ? WHERE username = ?;")
|
||||||
|
.bind(code)
|
||||||
|
.bind(&username)
|
||||||
|
.execute(&self.db_pool).await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(_) => self.send_login_message(&username, &new_email, code).await,
|
||||||
|
Err(_) => InvalidUsername
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn finish_change_email_flow(self, _: Context, username: String, token: String, login_code: u16) -> ErrorCode {
|
async fn finish_change_email_flow(self, _: Context, username: String, new_email: String, token: String, login_code: u16) -> ErrorCode {
|
||||||
todo!()
|
let result = self.is_authorized(&username, &token).await;
|
||||||
|
match result {
|
||||||
|
Ok(authorized) => {
|
||||||
|
if !authorized {
|
||||||
|
return Unauthorized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(error) => return error
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = self.is_email_taken(&new_email).await;
|
||||||
|
match result {
|
||||||
|
Ok(taken) => {
|
||||||
|
if taken {
|
||||||
|
return EmailTaken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(error) => return error
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.is_login_code_valid(&username, login_code).await.unwrap() {
|
||||||
|
return InvalidLoginCode
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = sqlx::query("UPDATE user SET new_email = NULL WHERE username = ?")
|
||||||
|
.bind(&username)
|
||||||
|
.execute(&self.db_pool).await;
|
||||||
|
|
||||||
|
let _ = sqlx::query("UPDATE user SET email = ? WHERE username = ?")
|
||||||
|
.bind(&new_email)
|
||||||
|
.bind(&username)
|
||||||
|
.execute(&self.db_pool).await;
|
||||||
|
|
||||||
|
NoError
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn change_username(self, _: Context, username: String, token: String, new_username: String) -> ErrorCode {
|
async fn change_username(self, _: Context, username: String, token: String, new_username: String) -> ErrorCode {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pub trait RealmAuth {
|
|||||||
|
|
||||||
//NOTE: Need to be the user
|
//NOTE: Need to be the user
|
||||||
async fn change_email_flow(username: String, new_email: String, token: String) -> ErrorCode;
|
async fn change_email_flow(username: String, new_email: String, token: String) -> ErrorCode;
|
||||||
async fn finish_change_email_flow(username: String, token: String, login_code: u16) -> ErrorCode;
|
async fn finish_change_email_flow(username: String, new_email: String, token: String, login_code: u16) -> ErrorCode;
|
||||||
async fn change_username(username: String, token: String, new_username: String) -> ErrorCode;
|
async fn change_username(username: String, token: String, new_username: String) -> ErrorCode;
|
||||||
async fn change_avatar(username: String, token: String, new_avatar: String) -> ErrorCode;
|
async fn change_avatar(username: String, token: String, new_avatar: String) -> ErrorCode;
|
||||||
async fn get_all_data(username: String, token: String) -> Result<AuthUser, ErrorCode>;
|
async fn get_all_data(username: String, token: String) -> Result<AuthUser, ErrorCode>;
|
||||||
@@ -19,8 +19,8 @@ pub trait RealmAuth {
|
|||||||
//NOTE: Anyone can call
|
//NOTE: Anyone can call
|
||||||
async fn get_avatar_for_user(username: String) -> Result<String, ErrorCode>;
|
async fn get_avatar_for_user(username: String) -> Result<String, ErrorCode>;
|
||||||
//TODO:
|
//TODO:
|
||||||
|
// Refactor all to use Result<_, ErrorCode> for ones with only -> ErrorCode
|
||||||
// Create account
|
// Create account
|
||||||
// Change email
|
|
||||||
// Change username
|
// Change username
|
||||||
// OAuth login, check against email, store token, take avatar: Google, Apple, GitHub, Discord
|
// OAuth login, check against email, store token, take avatar: Google, Apple, GitHub, Discord
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user