use super::*;
#[derive(Deserialize)]
pub struct Request {
pub token: String,
pub password: String,
}
#[derive(Serialize, Queryable, Selectable)]
#[diesel(table_name = schema::user)]
pub struct Response {
pub id: i32,
pub email: String,
}
#[put("")]
pub async fn route(
db: web::Data<Database>,
req: web::Json<Request>,
) -> Result<impl Responder, impl ResponseError> {
let mut req = req.into_inner();
if !user_client::validate::password(&req.password) {
return Err(ErrorCode::BadRequest);
}
let hashed_password = hashing::generate(&req.password);
req.password = hashed_password;
let returned: Result<(i32, String), diesel::result::Error> = web::block(move || {
use diesel::dsl::*;
let mut conn = db.get_conn();
conn.transaction(|conn| {
let user: Result<(Option<i32>, Option<String>), diesel::result::Error> =
schema::reset::table
.inner_join(schema::user::table.on(schema::user::id.eq(schema::reset::user)))
.select((schema::user::id.nullable(), schema::user::email.nullable()))
.filter(schema::reset::token.eq(req.token))
.first::<(Option<i32>, Option<String>)>(conn);
if user.is_err() {
return Err(user.unwrap_err());
}
let user = user.unwrap();
let user = (user.0.unwrap(), user.1.unwrap());
delete(schema::reset::table.filter(schema::reset::user.eq(user.0)))
.execute(conn)
.unwrap();
update(schema::user::table.filter(schema::user::id.eq(user.0)))
.set(schema::user::password.eq(req.password))
.execute(conn)
.unwrap();
Ok(user)
})
})
.await
.unwrap();
let returned = match returned {
Err(_) => return Err(ErrorCode::NotFound),
Ok(returned) => returned,
};
Ok(web::Json(Response {
id: returned.0,
email: returned.1,
}))
}