Tell the user if the reset password token is expired.

This commit is contained in:
Greg Burri 2024-11-09 18:58:39 +01:00
parent ed979719b5
commit 37f6de7a89
4 changed files with 34 additions and 25 deletions

View file

@ -74,12 +74,18 @@ pub enum AuthenticationResult {
}
#[derive(Debug)]
pub enum GetTokenResetPassword {
pub enum GetTokenResetPasswordResult {
PasswordAlreadyReset,
EmailUnknown,
Ok(String),
}
#[derive(Debug)]
pub enum ResetPasswordResult {
ResetTokenExpired,
Ok,
}
#[derive(Clone)]
pub struct Connection {
pool: Pool<Sqlite>,
@ -440,7 +446,7 @@ WHERE [id] = $1
&self,
email: &str,
validation_time: Duration,
) -> Result<GetTokenResetPassword> {
) -> Result<GetTokenResetPasswordResult> {
let mut tx = self.tx().await?;
if let Some(db_datetime_nullable) = sqlx::query_scalar::<_, Option<DateTime<Utc>>>(
@ -456,11 +462,11 @@ WHERE [email] = $1
{
if let Some(db_datetime) = db_datetime_nullable {
if Utc::now() - db_datetime <= validation_time {
return Ok(GetTokenResetPassword::PasswordAlreadyReset);
return Ok(GetTokenResetPasswordResult::PasswordAlreadyReset);
}
}
} else {
return Ok(GetTokenResetPassword::EmailUnknown);
return Ok(GetTokenResetPasswordResult::EmailUnknown);
}
let token = generate_token();
@ -480,7 +486,7 @@ WHERE [email] = $1
tx.commit().await?;
Ok(GetTokenResetPassword::Ok(token))
Ok(GetTokenResetPasswordResult::Ok(token))
}
pub async fn reset_password(
@ -488,7 +494,7 @@ WHERE [email] = $1
new_password: &str,
token: &str,
validation_time: Duration,
) -> Result<()> {
) -> Result<ResetPasswordResult> {
let mut tx = self.tx().await?;
// There is no index on [password_reset_token]. Is it useful?
if let (user_id, Some(db_datetime)) = sqlx::query_as::<_, (i64, Option<DateTime<Utc>>)>(
@ -503,9 +509,7 @@ WHERE [password_reset_token] = $1
.await?
{
if Utc::now() - db_datetime > validation_time {
return Err(DBError::Other(
"Can't reset password: validation time exceeded".to_string(),
));
return Ok(ResetPasswordResult::ResetTokenExpired);
}
// Remove all login tokens (for security reasons).
@ -530,7 +534,7 @@ WHERE [id] = $1
tx.commit().await?;
Ok(())
Ok(ResetPasswordResult::Ok)
} else {
Err(DBError::Other(
"Can't reset password: stored token or datetime not set (NULL)".to_string(),
@ -983,7 +987,7 @@ VALUES (
.get_token_reset_password(email, Duration::hours(1))
.await?
{
GetTokenResetPassword::EmailUnknown => Ok(()), // Nominal case.
GetTokenResetPasswordResult::EmailUnknown => Ok(()), // Nominal case.
other => panic!("{:?}", other),
}
}
@ -1031,7 +1035,7 @@ VALUES (
.get_token_reset_password(email, Duration::hours(1))
.await?
{
GetTokenResetPassword::Ok(token) => token,
GetTokenResetPasswordResult::Ok(token) => token,
other => panic!("{:?}", other),
};