backend/src/api/v1/auth/revoke.rs
Radical 8605b81e7b
All checks were successful
ci/woodpecker/push/build-and-publish Pipeline was successful
style: cargo clippy && format
2025-05-24 01:09:17 +02:00

63 lines
1.6 KiB
Rust

use actix_web::{HttpRequest, HttpResponse, post, web};
use argon2::{PasswordHash, PasswordVerifier};
use diesel::{ExpressionMethods, QueryDsl, delete};
use diesel_async::RunQueryDsl;
use serde::Deserialize;
use crate::{
Data,
api::v1::auth::check_access_token,
error::Error,
schema::refresh_tokens::{self, dsl as rdsl},
schema::users::dsl as udsl,
utils::get_auth_header,
};
#[derive(Deserialize)]
struct RevokeRequest {
password: String,
device_name: String,
}
// TODO: Should maybe be a delete request?
#[post("/revoke")]
pub async fn res(
req: HttpRequest,
revoke_request: web::Json<RevokeRequest>,
data: web::Data<Data>,
) -> Result<HttpResponse, Error> {
let headers = req.headers();
let auth_header = get_auth_header(headers)?;
let mut conn = data.pool.get().await?;
let uuid = check_access_token(auth_header, &mut conn).await?;
let database_password: String = udsl::users
.filter(udsl::uuid.eq(uuid))
.select(udsl::password)
.get_result(&mut conn)
.await?;
let hashed_password = PasswordHash::new(&database_password)
.map_err(|e| Error::PasswordHashError(e.to_string()))?;
if data
.argon2
.verify_password(revoke_request.password.as_bytes(), &hashed_password)
.is_err()
{
return Err(Error::Unauthorized(
"Wrong username or password".to_string(),
));
}
delete(refresh_tokens::table)
.filter(rdsl::uuid.eq(uuid))
.filter(rdsl::device_name.eq(&revoke_request.device_name))
.execute(&mut conn)
.await?;
Ok(HttpResponse::Ok().finish())
}