feat(api): added overwriting of zombie account on registration
This commit is contained in:
parent
cb354ca7b2
commit
31a8c80eca
|
@ -105,4 +105,15 @@ impl Account {
|
|||
Err(_) => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete(&self, pool: &PgPool) -> Result<()> {
|
||||
sqlx::query!(r#"DELETE FROM AuthTokens WHERE account = $1;"#, self.id)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
sqlx::query!(r#"DELETE FROM Accounts WHERE id = $1;"#, self.id)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,19 +41,34 @@ pub async fn register(
|
|||
return Ok(data::RegisterResponse::MalformedEmail);
|
||||
}
|
||||
|
||||
if Account::from_username(pool, &request.username)
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
return Ok(data::RegisterResponse::Conflict(
|
||||
data::RegisterConflict::Username,
|
||||
));
|
||||
// Check if the usernam is already taken
|
||||
if let Some(account) = Account::from_username(pool, &request.username).await? {
|
||||
// Check if the account that has taken the username is verified or has an open verification request.
|
||||
if account.verified
|
||||
|| VerificationToken::from_id(pool, account.id)
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
return Ok(data::RegisterResponse::Conflict(
|
||||
data::RegisterConflict::Username,
|
||||
));
|
||||
}
|
||||
// The found account is a Zombie account, we can delete it and continue.
|
||||
account.delete(pool).await?;
|
||||
}
|
||||
|
||||
if Account::from_email(pool, &request.email).await?.is_some() {
|
||||
return Ok(data::RegisterResponse::Conflict(
|
||||
data::RegisterConflict::Email,
|
||||
));
|
||||
// The same stuff for the email
|
||||
if let Some(account) = Account::from_email(pool, &request.email).await? {
|
||||
if account.verified
|
||||
|| VerificationToken::from_id(pool, account.id)
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
return Ok(data::RegisterResponse::Conflict(
|
||||
data::RegisterConflict::Email,
|
||||
));
|
||||
}
|
||||
account.delete(pool).await?;
|
||||
}
|
||||
|
||||
let account = Account::new(pool, &request.username, &request.email, &request.password).await?;
|
||||
|
@ -137,16 +152,14 @@ pub async fn delete(pool: &PgPool, auth: String) -> Result<data::DeleteResponse>
|
|||
None => return Ok(data::DeleteResponse::Unauthorized),
|
||||
};
|
||||
|
||||
sqlx::query!(
|
||||
r#"DELETE FROM AuthTokens WHERE account = $1;"#,
|
||||
token.account
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
sqlx::query!(r#"DELETE FROM Accounts WHERE id = $1;"#, token.account)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
match Account::from_id(pool, token.account).await? {
|
||||
Some(a) => a.delete(pool).await?,
|
||||
None => {
|
||||
return Err(anyhow::Error::msg(
|
||||
"Failed to delete account. Account not found in database",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(data::DeleteResponse::Success)
|
||||
}
|
||||
|
|
|
@ -156,6 +156,29 @@ impl VerificationToken {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn from_id(pool: &PgPool, account_id: i64) -> Result<Option<Self>> {
|
||||
let query_result = sqlx::query_as!(
|
||||
Self,
|
||||
r#"SELECT * FROM VerificationTokens WHERE account = $1;"#,
|
||||
account_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
.await;
|
||||
|
||||
match query_result {
|
||||
Ok(token) => {
|
||||
if token.expire.timestamp() > chrono::Utc::now().timestamp() {
|
||||
Ok(Some(token))
|
||||
} else {
|
||||
token.delete(pool).await?;
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
Err(sqlx::Error::RowNotFound) => Ok(None),
|
||||
Err(e) => Err(Error::new(e)),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn delete(&self, pool: &PgPool) -> Result<()> {
|
||||
sqlx::query!(
|
||||
r#"DELETE FROM VerificationTokens WHERE token = $1;"#,
|
||||
|
|
Loading…
Reference in New Issue