backend/api/v1/auth/
logout.rs

1use actix_web::{HttpRequest, HttpResponse, get, web};
2use diesel::{ExpressionMethods, delete};
3use diesel_async::RunQueryDsl;
4
5use crate::{
6    Data,
7    error::Error,
8    schema::refresh_tokens::{self, dsl},
9};
10
11/// `GET /api/v1/logout`
12///
13/// requires auth: kinda, needs refresh token set but no access token is technically required
14///
15/// ### Responses
16///
17/// 200 Logged out
18///
19/// 404 Refresh token is invalid
20///
21/// 401 Unauthorized (no refresh token found)
22///
23#[get("/logout")]
24pub async fn res(req: HttpRequest, data: web::Data<Data>) -> Result<HttpResponse, Error> {
25    let mut refresh_token_cookie = req.cookie("refresh_token").ok_or(Error::Unauthorized(
26        "request has no refresh token".to_string(),
27    ))?;
28
29    let refresh_token = String::from(refresh_token_cookie.value());
30
31    let mut conn = data.pool.get().await?;
32
33    let deleted = delete(refresh_tokens::table)
34        .filter(dsl::token.eq(refresh_token))
35        .execute(&mut conn)
36        .await?;
37
38    refresh_token_cookie.make_removal();
39
40    if deleted == 0 {
41        return Ok(HttpResponse::NotFound()
42            .cookie(refresh_token_cookie)
43            .finish());
44    }
45
46    Ok(HttpResponse::Ok().cookie(refresh_token_cookie).finish())
47}