use actix_web::body::{BoxBody, MessageBody}; use actix_web::dev::{ServiceRequest, ServiceResponse}; use actix_web::middleware::Next; use actix_web::web::Data; use actix_web::{Error, HttpMessage, HttpResponse}; use ::session::Session; use export::AppState; use crate::middleware::cookie::append_cookie; const SKIP_PREFIXES: [&str; 8] = [ "/healthz", "/readyz", "/api/docs", "/api/v1/auth/", "/api/v1/internal", "/assets", "/pages", "/swagger", ]; pub async fn revalidate( request: ServiceRequest, next: Next, ) -> Result, Error> where B: MessageBody + 'static, { if SKIP_PREFIXES .iter() .any(|prefix| request.path().starts_with(prefix)) { return Ok(next.call(request).await?.map_into_boxed_body()); } let Some(state) = request .app_data::>() .map(|value| value.get_ref().clone()) else { return Ok(next.call(request).await?.map_into_boxed_body()); }; let Some(session) = request.extensions().get::().cloned() else { return Ok(next.call(request).await?.map_into_boxed_body()); }; let Some(user_id) = session.uid() else { return Ok(next.call(request).await?.map_into_boxed_body()); }; let Some(version) = session.security_version().ok().flatten() else { return Ok(next.call(request).await?.map_into_boxed_body()); }; let Some(session_id) = session.session_id() else { return Ok(next.call(request).await?.map_into_boxed_body()); }; let Some(accounts) = request .app_data::>() .map(|value| value.get_ref().clone()) else { return Ok(next.call(request).await?.map_into_boxed_body()); }; let key = format!("auth:recheck:{session_id}:{version}"); if export::redis::get_string(&state.redis, &key) .await .ok() .flatten() .is_some() { return Ok(next.call(request).await?.map_into_boxed_body()); } match accounts.get_session(user_id, version, &session_id).await { Ok(_) => { let _ = export::redis::set_string( &state.redis, &key, "1", state.config.session.recheck_secs, ) .await; Ok(next.call(request).await?.map_into_boxed_body()) } Err(export::KenAuthError::Unauthenticated) | Err(export::KenAuthError::NotFound) => { let mut response = HttpResponse::Unauthorized().json(serde_json::json!({ "code": 401, "message": "session_revoked", "data": null, "error": null, "error_code": "session_revoked", "request_id": export::middleware::request_id(), })); append_cookie( &mut response, &session::clear_session_cookie(&state.config.session), ); Ok(request.into_response(response)) } Err(_) => Ok(next.call(request).await?.map_into_boxed_body()), } }