[[package]]
name = "allocator-api2"
-version = "0.2.18"
+version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
+checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f"
[[package]]
name = "android-tzdata"
[[package]]
name = "cc"
-version = "1.1.36"
+version = "1.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70"
+checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
dependencies = [
"shlex",
]
[[package]]
name = "fastrand"
-version = "2.1.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
+checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
[[package]]
name = "flume"
[[package]]
name = "tempfile"
-version = "3.13.0"
+version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
+checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
dependencies = [
"cfg-if",
"fastrand",
}
#[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>,
&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>>>(
{
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();
tx.commit().await?;
- Ok(GetTokenResetPassword::Ok(token))
+ Ok(GetTokenResetPasswordResult::Ok(token))
}
pub async fn reset_password(
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>>)>(
.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).
tx.commit().await?;
- Ok(())
+ Ok(ResetPasswordResult::Ok)
} else {
Err(DBError::Other(
"Can't reset password: stored token or datetime not set (NULL)".to_string(),
.get_token_reset_password(email, Duration::hours(1))
.await?
{
- GetTokenResetPassword::EmailUnknown => Ok(()), // Nominal case.
+ GetTokenResetPasswordResult::EmailUnknown => Ok(()), // Nominal case.
other => panic!("{:?}", other),
}
}
.get_token_reset_password(email, Duration::hours(1))
.await?
{
- GetTokenResetPassword::Ok(token) => token,
+ GetTokenResetPasswordResult::Ok(token) => token,
other => panic!("{:?}", other),
};
)
.await
{
- Ok(db::GetTokenResetPassword::PasswordAlreadyReset) => error_response(
+ Ok(db::GetTokenResetPasswordResult::PasswordAlreadyReset) => error_response(
AskResetPasswordError::EmailAlreadyReset,
&form_data.email,
user,
),
- Ok(db::GetTokenResetPassword::EmailUnknown) => {
+ Ok(db::GetTokenResetPasswordResult::EmailUnknown) => {
error_response(AskResetPasswordError::EmailUnknown, &form_data.email, user)
}
- Ok(db::GetTokenResetPassword::Ok(token)) => {
+ Ok(db::GetTokenResetPasswordResult::Ok(token)) => {
let url = utils::get_url_from_host(&host);
match email::send_email(
&form_data.email,
enum ResetPasswordError {
PasswordsNotEqual,
InvalidPassword,
+ TokenExpired,
DatabaseError,
}
}
.to_string(),
message: match error {
+ ResetPasswordError::TokenExpired => "Token expired, try to reset password again",
ResetPasswordError::DatabaseError => "Database error",
_ => "",
}
)
.await
{
- Ok(_) => Ok(MessageTemplate {
+ Ok(db::ResetPasswordResult::Ok) => Ok(MessageTemplate {
user,
message: "Your password has been reset",
}
.into_response()),
+ Ok(db::ResetPasswordResult::ResetTokenExpired) => {
+ error_response(ResetPasswordError::TokenExpired, &form_data, user)
+ }
Err(_) => error_response(ResetPasswordError::DatabaseError, &form_data, user),
}
}