From 9f0280c204549f30876ba7f8f056abc099bf859f Mon Sep 17 00:00:00 2001 From: antifallobst Date: Thu, 17 Aug 2023 03:17:20 +0200 Subject: [PATCH] feat(tokens): implemented token duplication protection --- src/api/account/handlers.rs | 13 ++++++++----- src/tokens.rs | 38 ++++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/api/account/handlers.rs b/src/api/account/handlers.rs index 1869d9a..db2a7be 100644 --- a/src/api/account/handlers.rs +++ b/src/api/account/handlers.rs @@ -92,7 +92,7 @@ pub async fn verify( return Ok(data::VerifyResponse::Blocked); } - let token = match VerificationToken::check(pool, request.token).await? { + let token = match VerificationToken::check(pool, &request.token).await? { Some(t) => t, None => return Ok(data::VerifyResponse::TokenUnknown), }; @@ -135,14 +135,17 @@ pub async fn delete(pool: &MySqlPool, token: String) -> Result t, None => return Ok(data::DeleteResponse::Unauthorized), }; - sqlx::query!(r#"DELETE FROM AuthTokens WHERE account = ?;"#, token.account) - .execute(pool) - .await?; + sqlx::query!( + r#"DELETE FROM AuthTokens WHERE account = ?;"#, + token.account + ) + .execute(pool) + .await?; sqlx::query!(r#"DELETE FROM Accounts WHERE id = ?;"#, token.account) .execute(pool) diff --git a/src/tokens.rs b/src/tokens.rs index 713892a..0bc87cb 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -1,4 +1,3 @@ -use crate::accounts::Account; use anyhow::{Error, Result}; use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono}; @@ -27,12 +26,16 @@ impl AuthToken { } }; - let token = Self { + let mut token = Self { token: uuid::Uuid::new_v4().simple().to_string(), account: account_id as u64, expire, }; + while AuthToken::check(pool, &token.token).await?.is_some() { + token.token = uuid::Uuid::new_v4().simple().to_string(); + } + sqlx::query!( r#" INSERT INTO AuthTokens (token, account, expire) VALUES (?, ?, ?); @@ -47,7 +50,7 @@ impl AuthToken { Ok(token) } - pub async fn check(pool: &MySqlPool, alphanumeric_token: String) -> Result> { + pub async fn check(pool: &MySqlPool, alphanumeric_token: &String) -> Result> { let query_result = sqlx::query!( r#"SELECT * FROM AuthTokens WHERE token = ?;"#, alphanumeric_token @@ -107,12 +110,19 @@ impl VerificationToken { } }; - let token = Self { + let mut token = Self { token: uuid::Uuid::new_v4().simple().to_string(), account: account_id as u64, expire, }; + while VerificationToken::check(pool, &token.token) + .await? + .is_some() + { + token.token = uuid::Uuid::new_v4().simple().to_string(); + } + sqlx::query!( r#" INSERT INTO VerificationTokens (token, account, expire) VALUES (?, ?, ?); @@ -127,7 +137,7 @@ impl VerificationToken { Ok(token) } - pub async fn check(pool: &MySqlPool, alphanumeric_token: String) -> Result> { + pub async fn check(pool: &MySqlPool, alphanumeric_token: &String) -> Result> { let query_result = sqlx::query!( r#"SELECT * FROM VerificationTokens WHERE token = ?;"#, alphanumeric_token @@ -162,13 +172,19 @@ impl VerificationToken { } pub async fn apply(&self, pool: &MySqlPool) -> Result<()> { - sqlx::query!(r#"DELETE FROM VerificationTokens WHERE token = ?;"#, self.token) - .execute(pool) - .await?; + sqlx::query!( + r#"DELETE FROM VerificationTokens WHERE token = ?;"#, + self.token + ) + .execute(pool) + .await?; - sqlx::query!(r#"UPDATE Accounts SET verified=true WHERE id = ?;"#, self.account) - .execute(pool) - .await?; + sqlx::query!( + r#"UPDATE Accounts SET verified=true WHERE id = ?;"#, + self.account + ) + .execute(pool) + .await?; Ok(()) }