From bb79ea56f87e46b34229061238d9e4f1bac9c112 Mon Sep 17 00:00:00 2001 From: 409 <409dev@protonmail.com> Date: Wed, 23 Jul 2025 14:13:16 +0200 Subject: [PATCH] automatically remove expired auth sessions --- backend/src/lib/outbound/postgres/auth.rs | 43 ++++++++++++++++++++++- backend/src/lib/outbound/postgres/mod.rs | 6 ++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/backend/src/lib/outbound/postgres/auth.rs b/backend/src/lib/outbound/postgres/auth.rs index e79bc2c..9a95062 100644 --- a/backend/src/lib/outbound/postgres/auth.rs +++ b/backend/src/lib/outbound/postgres/auth.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use anyhow::{Context as _, anyhow}; use argon2::{ Argon2, PasswordHash, PasswordVerifier as _, @@ -7,7 +9,8 @@ use argon2::{ }, }; use chrono::Utc; -use sqlx::{Acquire as _, PgConnection}; +use sqlx::{Acquire as _, PgConnection, PgPool}; +use tokio::task::JoinHandle; use uuid::Uuid; use crate::domain::warren::{ @@ -340,6 +343,44 @@ impl AuthRepository for Postgres { } impl Postgres { + pub(super) fn start_session_cleanup_task(pool: PgPool, interval: Duration) -> JoinHandle<()> { + tokio::spawn(async move { + loop { + { + let Ok(mut connection) = pool.acquire().await else { + break; + }; + + if let Ok(count) = Self::delete_expired_auth_sessions(&mut connection).await { + tracing::debug!("Removed {count} expired auth session(s)"); + } + } + + tokio::time::sleep(interval).await; + } + + tracing::debug!("Session cleanup task stopped"); + }) + } + + async fn delete_expired_auth_sessions( + connection: &mut PgConnection, + ) -> Result { + let delete_count = sqlx::query( + " + DELETE FROM + auth_sessions + WHERE + expires_at <= CURRENT_TIMESTAMP + ", + ) + .execute(connection) + .await? + .rows_affected(); + + Ok(delete_count) + } + async fn create_user( &self, connection: &mut PgConnection, diff --git a/backend/src/lib/outbound/postgres/mod.rs b/backend/src/lib/outbound/postgres/mod.rs index f1f2d59..3e568a3 100644 --- a/backend/src/lib/outbound/postgres/mod.rs +++ b/backend/src/lib/outbound/postgres/mod.rs @@ -1,11 +1,10 @@ -use std::str::FromStr as _; +use std::{str::FromStr as _, time::Duration}; use anyhow::Context as _; use sqlx::{ ConnectOptions as _, Connection as _, PgConnection, PgPool, postgres::{PgConnectOptions, PgPoolOptions}, }; - pub mod auth; pub mod warrens; @@ -58,6 +57,9 @@ impl Postgres { .await?; sqlx::migrate!("./migrations").run(&pool).await?; + // 3600 seconds = 1 hour + Self::start_session_cleanup_task(pool.clone(), Duration::from_secs(3600)); + Ok(Self { pool }) } }