parent
27be1efb74
commit
2d0f77af59
10 changed files with 13 additions and 40 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2678,7 +2678,6 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"sha2",
|
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"task-local-extensions",
|
"task-local-extensions",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -2711,7 +2710,6 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"sha2",
|
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|
|
@ -108,7 +108,6 @@ diesel_ltree = "0.3.0"
|
||||||
typed-builder = "0.15.0"
|
typed-builder = "0.15.0"
|
||||||
serial_test = "2.0.0"
|
serial_test = "2.0.0"
|
||||||
tokio = { version = "1.29.1", features = ["full"] }
|
tokio = { version = "1.29.1", features = ["full"] }
|
||||||
sha2 = "0.10.7"
|
|
||||||
regex = "1.9.0"
|
regex = "1.9.0"
|
||||||
once_cell = "1.18.0"
|
once_cell = "1.18.0"
|
||||||
diesel-derive-newtype = "2.1.0"
|
diesel-derive-newtype = "2.1.0"
|
||||||
|
|
|
@ -342,9 +342,8 @@ pub async fn send_password_reset_email(
|
||||||
let token = uuid::Uuid::new_v4().to_string();
|
let token = uuid::Uuid::new_v4().to_string();
|
||||||
|
|
||||||
// Insert the row
|
// Insert the row
|
||||||
let token2 = token.clone();
|
|
||||||
let local_user_id = user.local_user.id;
|
let local_user_id = user.local_user.id;
|
||||||
PasswordResetRequest::create_token(pool, local_user_id, &token2).await?;
|
PasswordResetRequest::create_token(pool, local_user_id, token.clone()).await?;
|
||||||
|
|
||||||
let email = &user.local_user.email.clone().expect("email");
|
let email = &user.local_user.email.clone().expect("email");
|
||||||
let lang = get_interface_language(user);
|
let lang = get_interface_language(user);
|
||||||
|
|
|
@ -33,7 +33,6 @@ http = { workspace = true }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
uuid = { workspace = true }
|
uuid = { workspace = true }
|
||||||
sha2 = { workspace = true }
|
|
||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
|
|
|
@ -22,7 +22,6 @@ full = [
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"sha2",
|
|
||||||
"regex",
|
"regex",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -60,7 +59,6 @@ diesel-async = { workspace = true, features = [
|
||||||
"postgres",
|
"postgres",
|
||||||
"deadpool",
|
"deadpool",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
sha2 = { workspace = true, optional = true }
|
|
||||||
regex = { workspace = true, optional = true }
|
regex = { workspace = true, optional = true }
|
||||||
once_cell = { workspace = true, optional = true }
|
once_cell = { workspace = true, optional = true }
|
||||||
diesel_ltree = { workspace = true, optional = true }
|
diesel_ltree = { workspace = true, optional = true }
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
newtypes::LocalUserId,
|
newtypes::LocalUserId,
|
||||||
schema::password_reset_request::dsl::{
|
schema::password_reset_request::dsl::{local_user_id, password_reset_request, published, token},
|
||||||
local_user_id,
|
|
||||||
password_reset_request,
|
|
||||||
published,
|
|
||||||
token_encrypted,
|
|
||||||
},
|
|
||||||
source::password_reset_request::{PasswordResetRequest, PasswordResetRequestForm},
|
source::password_reset_request::{PasswordResetRequest, PasswordResetRequestForm},
|
||||||
traits::Crud,
|
traits::Crud,
|
||||||
utils::{get_conn, DbPool},
|
utils::{get_conn, DbPool},
|
||||||
|
@ -17,7 +12,6 @@ use diesel::{
|
||||||
QueryDsl,
|
QueryDsl,
|
||||||
};
|
};
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
use sha2::{Digest, Sha256};
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Crud for PasswordResetRequest {
|
impl Crud for PasswordResetRequest {
|
||||||
|
@ -49,29 +43,22 @@ impl PasswordResetRequest {
|
||||||
pub async fn create_token(
|
pub async fn create_token(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
from_local_user_id: LocalUserId,
|
from_local_user_id: LocalUserId,
|
||||||
token: &str,
|
token_: String,
|
||||||
) -> Result<PasswordResetRequest, Error> {
|
) -> Result<PasswordResetRequest, Error> {
|
||||||
let mut hasher = Sha256::new();
|
|
||||||
hasher.update(token);
|
|
||||||
let token_hash: String = bytes_to_hex(hasher.finalize().to_vec());
|
|
||||||
|
|
||||||
let form = PasswordResetRequestForm {
|
let form = PasswordResetRequestForm {
|
||||||
local_user_id: from_local_user_id,
|
local_user_id: from_local_user_id,
|
||||||
token_encrypted: token_hash,
|
token: token_,
|
||||||
};
|
};
|
||||||
|
|
||||||
Self::create(pool, &form).await
|
Self::create(pool, &form).await
|
||||||
}
|
}
|
||||||
pub async fn read_from_token(
|
pub async fn read_from_token(
|
||||||
pool: &mut DbPool<'_>,
|
pool: &mut DbPool<'_>,
|
||||||
token: &str,
|
token_: &str,
|
||||||
) -> Result<PasswordResetRequest, Error> {
|
) -> Result<PasswordResetRequest, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
let mut hasher = Sha256::new();
|
|
||||||
hasher.update(token);
|
|
||||||
let token_hash: String = bytes_to_hex(hasher.finalize().to_vec());
|
|
||||||
password_reset_request
|
password_reset_request
|
||||||
.filter(token_encrypted.eq(token_hash))
|
.filter(token.eq(token_))
|
||||||
.filter(published.gt(now - 1.days()))
|
.filter(published.gt(now - 1.days()))
|
||||||
.first::<Self>(conn)
|
.first::<Self>(conn)
|
||||||
.await
|
.await
|
||||||
|
@ -91,14 +78,6 @@ impl PasswordResetRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bytes_to_hex(bytes: Vec<u8>) -> String {
|
|
||||||
let mut str = String::new();
|
|
||||||
for byte in bytes {
|
|
||||||
str = format!("{str}{byte:02x}");
|
|
||||||
}
|
|
||||||
str
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#![allow(clippy::unwrap_used)]
|
#![allow(clippy::unwrap_used)]
|
||||||
|
@ -142,17 +121,16 @@ mod tests {
|
||||||
let inserted_local_user = LocalUser::create(pool, &new_local_user).await.unwrap();
|
let inserted_local_user = LocalUser::create(pool, &new_local_user).await.unwrap();
|
||||||
|
|
||||||
let token = "nope";
|
let token = "nope";
|
||||||
let token_encrypted_ = "ca3704aa0b06f5954c79ee837faa152d84d6b2d42838f0637a15eda8337dbdce";
|
|
||||||
|
|
||||||
let inserted_password_reset_request =
|
let inserted_password_reset_request =
|
||||||
PasswordResetRequest::create_token(pool, inserted_local_user.id, token)
|
PasswordResetRequest::create_token(pool, inserted_local_user.id, token.to_string())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let expected_password_reset_request = PasswordResetRequest {
|
let expected_password_reset_request = PasswordResetRequest {
|
||||||
id: inserted_password_reset_request.id,
|
id: inserted_password_reset_request.id,
|
||||||
local_user_id: inserted_local_user.id,
|
local_user_id: inserted_local_user.id,
|
||||||
token_encrypted: token_encrypted_.to_string(),
|
token: token.to_string(),
|
||||||
published: inserted_password_reset_request.published,
|
published: inserted_password_reset_request.published,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -535,7 +535,7 @@ diesel::table! {
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
password_reset_request (id) {
|
password_reset_request (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
token_encrypted -> Text,
|
token -> Text,
|
||||||
published -> Timestamp,
|
published -> Timestamp,
|
||||||
local_user_id -> Int4,
|
local_user_id -> Int4,
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::schema::password_reset_request;
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = password_reset_request))]
|
#[cfg_attr(feature = "full", diesel(table_name = password_reset_request))]
|
||||||
pub struct PasswordResetRequest {
|
pub struct PasswordResetRequest {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub token_encrypted: String,
|
pub token: String,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub local_user_id: LocalUserId,
|
pub local_user_id: LocalUserId,
|
||||||
}
|
}
|
||||||
|
@ -16,5 +16,5 @@ pub struct PasswordResetRequest {
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = password_reset_request))]
|
#[cfg_attr(feature = "full", diesel(table_name = password_reset_request))]
|
||||||
pub struct PasswordResetRequestForm {
|
pub struct PasswordResetRequestForm {
|
||||||
pub local_user_id: LocalUserId,
|
pub local_user_id: LocalUserId,
|
||||||
pub token_encrypted: String,
|
pub token: String,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
alter table password_reset_request rename column token to token_encrypted;
|
1
migrations/2023-08-02-144930_password-reset-token/up.sql
Normal file
1
migrations/2023-08-02-144930_password-reset-token/up.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
alter table password_reset_request rename column token_encrypted to token;
|
Loading…
Reference in a new issue