avt cleanup (fix paging) (#1312)

This commit is contained in:
Brandon Thomas
2026-04-07 00:29:18 -04:00
committed by GitHub
parent a0e50067bb
commit fd9f002615
28 changed files with 350 additions and 138 deletions
@@ -0,0 +1,142 @@
use actix_web::cookie::time::OffsetDateTime;
use actix_web::cookie::{Cookie, SameSite};
use actix_web::HttpRequest;
use log::warn;
use crate::sessions::anonymous_visitor_tracking::avt_cookie_payload::AvtCookiePayload;
use crate::sessions::anonymous_visitor_tracking::avt_cookie_payload_error::AvtCookiePayloadError;
use crate::sessions::anonymous_visitor_tracking::avt_payload_signer::AvtPayloadSigner;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
const VISITOR_COOKIE_NAME : &str = "visitor";
/// Handle "anonymous visitor tracking" cookies.
/// This enables us to associate results with an anonymous user for a better experience,
/// as well as do some form of return visitor tracking.
#[derive(Clone)]
pub struct AvtCookieManager {
cookie_domain: String,
payload_signer: AvtPayloadSigner,
}
impl AvtCookieManager {
pub fn new(cookie_domain: &str, hmac_secret: &str) -> Result<Self, AvtCookiePayloadError> {
Ok(Self {
cookie_domain: cookie_domain.to_string(),
payload_signer: AvtPayloadSigner::new(hmac_secret)?,
})
}
pub fn make_new_cookie(&self) -> Result<Cookie, AvtCookiePayloadError> {
let token = AnonymousVisitorTrackingToken::generate();
self.make_new_cookie_with_apriori_token(&token)
}
pub fn make_new_cookie_with_apriori_token(
&self,
token: &AnonymousVisitorTrackingToken,
) -> Result<Cookie, AvtCookiePayloadError> {
let payload = AvtCookiePayload::from_token(token.clone());
let jwt_string = self.payload_signer.encode(&payload)?;
let make_secure = !self.cookie_domain.to_lowercase().contains("jungle.horse")
&& !self.cookie_domain.to_lowercase().contains("localhost");
let same_site = if make_secure {
SameSite::None // NB: Allow usage from other domains
} else {
SameSite::Lax // NB: You can't set "SameSite=None" on non-secure cookies
};
Ok(Cookie::build(VISITOR_COOKIE_NAME, jwt_string)
.secure(make_secure) // HTTPS-only
.same_site(same_site)
.permanent()
.path("/") // NB: Otherwise it'll be set to `/v1`
//.domain(&self.cookie_domain)
//.http_only(true) // Not exposed to Javascript
.finish())
}
pub fn make_delete_cookie(&self) -> Cookie {
let mut cookie = Cookie::build(VISITOR_COOKIE_NAME, "DELETED")
.expires(OffsetDateTime::UNIX_EPOCH)
.path("/") // NB: Otherwise it'll be set to `/v1`
.finish();
cookie.make_removal();
cookie
}
pub fn decode_cookie_payload(
&self,
visitor_cookie: &Cookie,
) -> Result<AvtCookiePayload, AvtCookiePayloadError> {
self.payload_signer.decode(visitor_cookie.value())
}
pub fn decode_cookie_payload_from_request(
&self,
request: &HttpRequest,
) -> Result<Option<AvtCookiePayload>, AvtCookiePayloadError> {
let cookie = match request.cookie(VISITOR_COOKIE_NAME) {
None => return Ok(None),
Some(cookie) => cookie,
};
match self.decode_cookie_payload(&cookie) {
Err(e) => {
warn!("Visitor cookie decode error: {:?}", e);
Err(e)
},
Ok(payload) => Ok(Some(payload)),
}
}
pub fn get_avt_token_from_request(
&self,
request: &HttpRequest,
) -> Option<AnonymousVisitorTrackingToken> {
self.decode_cookie_payload_from_request(request)
.ok()
.flatten()
.map(|payload| payload.avt_token)
}
}
#[cfg(test)]
mod tests {
use actix_web::test::TestRequest;
use crate::sessions::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
#[test]
fn test_create_cookie() {
// NB: Stable encoding test. If this changes we should bump the cookie version
// so we don't accidentally invalidate visitor tracking on existing cookies.
let manager = AvtCookieManager::new("fakeyou.com", "secret").unwrap();
let token = AnonymousVisitorTrackingToken::new_from_str("avt_ex_anonymous_visitor_tracking_token");
let cookie = manager.make_new_cookie_with_apriori_token(&token).unwrap();
assert_eq!(cookie.value(), "eyJhbGciOiJIUzI1NiJ9.eyJhdnRfdG9rZW4iOiJhdnRfZXhfYW5vbnltb3VzX3Zpc2l0b3JfdHJhY2tpbmdfdG9rZW4iLCJjb29raWVfdmVyc2lvbiI6IjEifQ.w0KRxBxiyBfTZGxaezRa0IgD8ojmCnhRH4SS33Nq3O8");
}
#[test]
fn test_cookie_round_trip() {
let manager = AvtCookieManager::new("fakeyou.com", "secret").unwrap();
let token = AnonymousVisitorTrackingToken::new_from_str("avt_ex_anonymous_visitor_tracking_token");
let cookie = manager.make_new_cookie_with_apriori_token(&token).unwrap();
let http_request = TestRequest::default()
.cookie(cookie)
.to_http_request();
let decoded = manager.decode_cookie_payload_from_request(&http_request)
.expect("no error")
.expect("must exist");
assert_eq!(decoded.avt_token.as_str(), "avt_ex_anonymous_visitor_tracking_token");
assert_eq!(decoded.cookie_version, 1);
}
}
@@ -1,7 +1,7 @@
use std::collections::BTreeMap;
use std::str::FromStr;
use crate::error::internal_error::InternalError;
use crate::sessions::anonymous_visitor_tracking::avt_cookie_payload_error::AvtCookiePayloadError;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
/**
@@ -43,18 +43,18 @@ impl AvtCookiePayload {
}
}
pub fn from_map(map: BTreeMap<String, String>) -> Result<Self, InternalError> {
pub fn from_map(map: BTreeMap<String, String>) -> Result<Self, AvtCookiePayloadError> {
let avt_token = map.get("avt_token")
.ok_or_else(|| InternalError::VisitorCookieMissingField("avt_token"))?;
.ok_or(AvtCookiePayloadError::MissingField("avt_token"))?;
let cookie_version = map
.get("cookie_version")
.ok_or_else(|| InternalError::VisitorCookieMissingField("cookie_version"))?;
.ok_or(AvtCookiePayloadError::MissingField("cookie_version"))?;
let avt_token = AnonymousVisitorTrackingToken::new_from_str(avt_token);
let cookie_version = u32::from_str(cookie_version)
.map_err(|e| InternalError::VisitorCookieError(
.map_err(|e| AvtCookiePayloadError::PayloadDecodeError(
format!("invalid integer for cookie_version: {:?}, version: {}", e, cookie_version)))?;
Ok(AvtCookiePayload {
@@ -75,7 +75,7 @@ impl AvtCookiePayload {
mod tests {
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
use crate::http_server::cookies::anonymous_visitor_tracking::avt_cookie_payload::AvtCookiePayload;
use crate::sessions::anonymous_visitor_tracking::avt_cookie_payload::AvtCookiePayload;
#[test]
fn test_new() {
@@ -0,0 +1,55 @@
use std::error::Error;
use std::fmt::{Display, Formatter};
use jwt_signer::jwt_signer_error::JwtSignerError;
#[derive(Debug)]
pub enum AvtCookiePayloadError {
/// AVT cookie payload is missing a required field.
MissingField(&'static str),
/// Generic decode error (e.g. invalid integer for cookie_version).
PayloadDecodeError(String),
/// Error encoding, decoding, or constructing the JWT signer.
JwtSigner(JwtSignerError),
}
impl AvtCookiePayloadError {
pub fn is_server_error(&self) -> bool {
match self {
// JWT verify errors (eg. forged cookies) → 400 bad input.
AvtCookiePayloadError::JwtSigner(JwtSignerError::JwtVerifyError(_)) => {
false
},
// Server-side JWT signer failures (bad HMAC config, signing failure) → 500.
AvtCookiePayloadError::JwtSigner(
JwtSignerError::JwtInvalidKeyLength | JwtSignerError::JwtSignError(_)
) => {
true
},
// Other payload decode failures (how did these make it into the wild!?) → 500
AvtCookiePayloadError::MissingField(_) | AvtCookiePayloadError::PayloadDecodeError(_) => {
true
}
}
}
}
impl Display for AvtCookiePayloadError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::MissingField(field) => write!(f, "AVT cookie missing field: {}", field),
Self::PayloadDecodeError(reason) => write!(f, "AVT cookie decode error: {}", reason),
Self::JwtSigner(e) => write!(f, "JWT signer error: {}", e),
}
}
}
impl Error for AvtCookiePayloadError {}
impl From<JwtSignerError> for AvtCookiePayloadError {
fn from(err: JwtSignerError) -> Self {
Self::JwtSigner(err)
}
}
@@ -0,0 +1,77 @@
use crate::sessions::anonymous_visitor_tracking::avt_cookie_payload::AvtCookiePayload;
use crate::sessions::anonymous_visitor_tracking::avt_cookie_payload_error::AvtCookiePayloadError;
use jwt_signer::jwt_signer::JwtSigner;
/// Signs and verifies the AVT cookie payload using HMAC-signed JWTs.
/// This module is intentionally HTTP-agnostic. The HTTP / cookie wrapper lives in `avt_cookie_manager`.
#[derive(Clone)]
pub struct AvtPayloadSigner {
jwt_signer: JwtSigner,
}
impl AvtPayloadSigner {
pub fn new(hmac_secret: &str) -> Result<Self, AvtCookiePayloadError> {
Ok(Self {
jwt_signer: JwtSigner::new(hmac_secret)?,
})
}
pub fn encode(&self, payload: &AvtCookiePayload) -> Result<String, AvtCookiePayloadError> {
let claims = payload.to_map();
let jwt_string = self.jwt_signer.claims_to_jwt(&claims)?;
Ok(jwt_string)
}
pub fn decode(&self, jwt: &str) -> Result<AvtCookiePayload, AvtCookiePayloadError> {
let claims = self.jwt_signer.jwt_to_claims(jwt)?;
AvtCookiePayload::from_map(claims)
}
}
#[cfg(test)]
mod tests {
use crate::sessions::anonymous_visitor_tracking::avt_cookie_payload::AvtCookiePayload;
use crate::sessions::anonymous_visitor_tracking::avt_payload_signer::AvtPayloadSigner;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
#[test]
fn test_encode() {
// NB: Stable encoding test. If this changes we should bump the cookie version.
let signer = AvtPayloadSigner::new("fake_secret").unwrap();
let token = AnonymousVisitorTrackingToken::new_from_str("avt_ex_anonymous_visitor_tracking_token");
let payload = AvtCookiePayload::from_token(token);
let encoded = signer.encode(&payload).unwrap();
assert_eq!(
encoded,
"eyJhbGciOiJIUzI1NiJ9.eyJhdnRfdG9rZW4iOiJhdnRfZXhfYW5vbnltb3VzX3Zpc2l0b3JfdHJhY2tpbmdfdG9rZW4iLCJjb29raWVfdmVyc2lvbiI6IjEifQ.5jgQfSXue684okKBzW3847jEhL7eLQKzelyAkgnwe_I"
);
}
#[test]
fn test_decode_version_1() {
// NB: Version 1 payload. The expected encoded value below was generated by `test_encode`.
let payload =
"eyJhbGciOiJIUzI1NiJ9.eyJhdnRfdG9rZW4iOiJhdnRfZXhfYW5vbnltb3VzX3Zpc2l0b3JfdHJhY2tpbmdfdG9rZW4iLCJjb29raWVfdmVyc2lvbiI6IjEifQ.5jgQfSXue684okKBzW3847jEhL7eLQKzelyAkgnwe_I";
let signer = AvtPayloadSigner::new("fake_secret").unwrap();
let decoded = signer.decode(payload).unwrap();
assert_eq!(decoded.avt_token.as_str(), "avt_ex_anonymous_visitor_tracking_token");
assert_eq!(decoded.cookie_version, 1);
}
#[test]
fn test_round_trip() {
let signer = AvtPayloadSigner::new("fake_secret").unwrap();
let token = AnonymousVisitorTrackingToken::new_from_str("avt_ex_anonymous_visitor_tracking_token");
let payload = AvtCookiePayload::from_token(token);
let encoded = signer.encode(&payload).unwrap();
let decoded = signer.decode(&encoded).unwrap();
assert_eq!(decoded.avt_token.as_str(), "avt_ex_anonymous_visitor_tracking_token");
assert_eq!(decoded.cookie_version, 1);
}
}
@@ -0,0 +1,4 @@
pub mod avt_cookie_manager;
pub mod avt_cookie_payload;
pub mod avt_cookie_payload_error;
pub mod avt_payload_signer;
@@ -1,4 +1,2 @@
pub mod http_user_session_manager;
pub mod http_user_session_payload;
pub mod http_user_session_payload_error;
pub mod http_user_session_payload_signer;
pub mod anonymous_visitor_tracking;
pub mod user_sessions;
@@ -8,9 +8,9 @@ use actix_web::cookie::{Cookie, SameSite};
use actix_web::HttpRequest;
use log::warn;
use crate::sessions::http_user_session_payload::HttpUserSessionPayload;
use crate::sessions::http_user_session_payload_signer::HttpUserSessionPayloadSigner;
use crate::sessions::http_user_session_payload_error::HttpUserSessionPayloadError;
use crate::sessions::user_sessions::http_user_session_payload::HttpUserSessionPayload;
use crate::sessions::user_sessions::http_user_session_payload_signer::HttpUserSessionPayloadSigner;
use crate::sessions::user_sessions::http_user_session_payload_error::HttpUserSessionPayloadError;
use tokens::tokens::user_sessions::UserSessionToken;
use tokens::tokens::users::UserToken;
@@ -170,7 +170,7 @@ mod tests {
use tokens::tokens::user_sessions::UserSessionToken;
use tokens::tokens::users::UserToken;
use crate::sessions::http_user_session_manager::HttpUserSessionManager;
use crate::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
#[test]
fn test_create_cookie_payload() {
@@ -12,6 +12,27 @@ pub enum HttpUserSessionPayloadError {
JwtSigner(JwtSignerError),
}
impl HttpUserSessionPayloadError {
pub fn is_server_error(&self) -> bool {
match self {
// Client HTTP header errors → 400 bad input.
HttpUserSessionPayloadError::HttpSessionHeaderError(_) => {
false
}
// JWT verify errors (eg. forged cookies) → 400 bad input.
HttpUserSessionPayloadError::JwtSigner(JwtSignerError::JwtVerifyError(_)) => {
false
}
// Server-side JWT signer failures (bad HMAC config, signing failure) → 500.
HttpUserSessionPayloadError::JwtSigner(
JwtSignerError::JwtInvalidKeyLength | JwtSignerError::JwtSignError(_)
) => {
true
},
}
}
}
impl Display for HttpUserSessionPayloadError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
@@ -1,7 +1,7 @@
use std::collections::BTreeMap;
use crate::sessions::http_user_session_payload::HttpUserSessionPayload;
use crate::sessions::http_user_session_payload_error::HttpUserSessionPayloadError;
use crate::sessions::user_sessions::http_user_session_payload::HttpUserSessionPayload;
use crate::sessions::user_sessions::http_user_session_payload_error::HttpUserSessionPayloadError;
use jwt_signer::jwt_signer::JwtSigner;
use tokens::tokens::user_sessions::UserSessionToken;
use tokens::tokens::users::UserToken;
@@ -62,7 +62,7 @@ impl HttpUserSessionPayloadSigner {
#[cfg(test)]
mod tests {
use crate::sessions::http_user_session_payload_signer::HttpUserSessionPayloadSigner;
use crate::sessions::user_sessions::http_user_session_payload_signer::HttpUserSessionPayloadSigner;
use tokens::tokens::user_sessions::UserSessionToken;
use tokens::tokens::users::UserToken;
@@ -0,0 +1,4 @@
pub mod http_user_session_manager;
pub mod http_user_session_payload;
pub mod http_user_session_payload_error;
pub mod http_user_session_payload_signer;
@@ -5,7 +5,7 @@ use crate::endpoints::checkout_with_user_signup::user_creation_case::user_creati
use crate::endpoints::checkout_with_user_signup::user_exists_case::user_exists_case;
use crate::utils::artcraft_stripe_config::ArtcraftStripeConfigWithClient;
use crate::utils::common_web_error::CommonWebError;
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_web::web::{Data, Json};
use actix_web::{web, HttpRequest, HttpResponse};
use artcraft_api_defs::stripe_artcraft::create_create_new_user_account_and_subscription_checkout::{PlanBillingCadence, SessionDetails, StripeArtcraftCreateSubscriptionCheckoutWithUserSignupRequest, StripeArtcraftCreateSubscriptionCheckoutWithUserSignupResponse, UserDetails};
@@ -4,7 +4,8 @@ use std::sync::Arc;
use crate::http_server::common_responses::common_web_error::CommonWebError;
use crate::http_server::session::session_checker_error::SessionCheckerError;
use crate::http_server::web_utils::user_session::require_user_session::RequireUserSessionError;
use actix_artcraft::sessions::http_user_session_payload_error::HttpUserSessionPayloadError;
use actix_artcraft::sessions::anonymous_visitor_tracking::avt_cookie_payload_error::AvtCookiePayloadError;
use actix_artcraft::sessions::user_sessions::http_user_session_payload_error::HttpUserSessionPayloadError;
use actix_http::StatusCode;
use actix_web::{HttpResponse, HttpResponseBuilder, ResponseError};
use anyhow::anyhow;
@@ -198,9 +199,22 @@ impl From<RequireUserSessionError> for AdvancedCommonWebError {
}
impl From<HttpUserSessionPayloadError> for AdvancedCommonWebError {
fn from(_value: HttpUserSessionPayloadError) -> Self {
// Any session error (bad header, bad JWT, construction failure) becomes 401.
Self::NotAuthorized
fn from(err: HttpUserSessionPayloadError) -> Self {
if err.is_server_error() {
Self::from_error(err)
} else {
Self::BadInputWithSimpleMessage("invalid session".to_string())
}
}
}
impl From<AvtCookiePayloadError> for AdvancedCommonWebError {
fn from(err: AvtCookiePayloadError) -> Self {
if err.is_server_error() {
Self::from_error(err)
} else {
Self::BadInputWithSimpleMessage("invalid AVT cookie".to_string())
}
}
}
@@ -1,99 +0,0 @@
use actix_web::cookie::time::OffsetDateTime;
use actix_web::cookie::{Cookie, SameSite};
use actix_web::HttpRequest;
use anyhow::anyhow;
use log::warn;
use crate::error::internal_error::InternalError;
use crate::http_server::cookies::anonymous_visitor_tracking::avt_cookie_payload::AvtCookiePayload;
use jwt_signer::jwt_signer::JwtSigner;
use errors::AnyhowResult;
use tokens::tokens::anonymous_visitor_tracking::AnonymousVisitorTrackingToken;
const VISITOR_COOKIE_NAME : &str = "visitor";
/// Handle "anonymous visitor tracking" cookies.
/// This enables us to associate results with an anonymous user for a better experience,
/// as well as do some form of return visitor tracking.
#[derive(Clone)]
pub struct AvtCookieManager {
cookie_domain: String,
jwt_signer: JwtSigner,
}
impl AvtCookieManager {
pub fn new(cookie_domain: &str, hmac_secret: &str) -> AnyhowResult<Self> {
Ok(Self {
cookie_domain: cookie_domain.to_string(),
jwt_signer: JwtSigner::new(hmac_secret)?,
})
}
pub fn make_new_cookie(&self) -> AnyhowResult<Cookie> {
let token = AnonymousVisitorTrackingToken::generate();
self.make_new_cookie_with_apriori_token(&token)
}
pub fn make_new_cookie_with_apriori_token(&self, token: &AnonymousVisitorTrackingToken) -> AnyhowResult<Cookie> {
let payload = AvtCookiePayload::from_token(token.clone());
let claims = payload.to_map();
let jwt_string = self.jwt_signer.claims_to_jwt(&claims)?;
let make_secure = !self.cookie_domain.to_lowercase().contains("jungle.horse")
&& !self.cookie_domain.to_lowercase().contains("localhost");
let same_site = if make_secure {
SameSite::None // NB: Allow usage from other domains
} else {
SameSite::Lax // NB: You can't set "SameSite=None" on non-secure cookies
};
Ok(Cookie::build(VISITOR_COOKIE_NAME, jwt_string)
.secure(make_secure) // HTTPS-only
.same_site(same_site)
.permanent()
.path("/") // NB: Otherwise it'll be set to `/v1`
//.domain(&self.cookie_domain)
//.http_only(true) // Not exposed to Javascript
.finish())
}
pub fn make_delete_cookie(&self) -> Cookie {
let mut cookie = Cookie::build(VISITOR_COOKIE_NAME, "DELETED")
.expires(OffsetDateTime::UNIX_EPOCH)
.path("/") // NB: Otherwise it'll be set to `/v1`
.finish();
cookie.make_removal();
cookie
}
pub fn decode_cookie_payload(&self, visitor_cookie: &Cookie) -> AnyhowResult<AvtCookiePayload> {
let cookie_contents = visitor_cookie.value().to_string();
let claims = self.jwt_signer.jwt_to_claims(&cookie_contents)?;
let payload = AvtCookiePayload::from_map(claims)?;
Ok(payload)
}
pub fn decode_cookie_payload_from_request(&self, request: &HttpRequest) -> Result<Option<AvtCookiePayload>, InternalError> {
let cookie = match request.cookie(VISITOR_COOKIE_NAME) {
None => return Ok(None),
Some(cookie) => cookie,
};
match self.decode_cookie_payload(&cookie) {
Err(e) => {
warn!("Visitor cookie decode error: {:?}", e);
Err(InternalError::VisitorCookieError(e.to_string()))
},
Ok(payload) => Ok(Some(payload)),
}
}
pub fn get_avt_token_from_request(&self, request: &HttpRequest) -> Option<AnonymousVisitorTrackingToken> {
self.decode_cookie_payload_from_request(request)
.ok()
.flatten()
.map(|payload| payload.avt_token)
}
}
@@ -1,2 +0,0 @@
pub mod avt_cookie_manager;
pub mod avt_cookie_payload;
@@ -1 +0,0 @@
pub mod anonymous_visitor_tracking;
@@ -1,4 +1,4 @@
use crate::http_server::cookies::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use actix_artcraft::sessions::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use crate::http_server::endpoints::app_state::components::get_permissions::{get_permissions, AppStatePermissions};
use crate::http_server::endpoints::app_state::components::get_premium_info::{get_premium_info, AppStatePremiumInfo};
use crate::http_server::endpoints::app_state::components::get_server_info::{get_server_info, AppStateServerInfo};
@@ -12,7 +12,7 @@ use crate::http_server::validations::validate_passwords::validate_passwords;
use crate::http_server::validations::validate_username::validate_username;
use crate::util::enroll_in_studio::enroll_in_studio;
use actix_artcraft::requests::get_request_signup_source_enum::get_request_signup_source_enum;
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::{web, HttpRequest, HttpResponse};
@@ -10,7 +10,7 @@ use crate::http_server::endpoints::users::google_sso::check_claims::check_claims
use crate::http_server::endpoints::users::google_sso::handle_existing_sso_account::{handle_existing_sso_account, ExistingAccountArgs};
use crate::http_server::endpoints::users::google_sso::handle_new_sso_account::{handle_new_sso_account, NewSsoArgs};
use crate::state::certs::google_sign_in_cert::GoogleSignInCert;
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::web::{Data, Json};
@@ -1,7 +1,7 @@
use std::fmt;
use std::fmt::Formatter;
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::{web, HttpRequest, HttpResponse};
@@ -5,7 +5,7 @@
use std::fmt;
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_web::error::ResponseError;
use actix_web::http::StatusCode;
use actix_web::{web, HttpRequest, HttpResponse};
@@ -1,6 +1,6 @@
use std::fmt::Display;
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_web::http::StatusCode;
use actix_web::{web, HttpRequest, HttpResponse, ResponseError};
use http_server_common::request::get_request_ip::get_request_ip;
@@ -12,7 +12,7 @@ use enums::by_table::users::user_feature_flag::UserFeatureFlag;
use crate::http_server::common_responses::advanced_common_web_error::AdvancedCommonWebError;
use crate::http_server::common_responses::user_details_lite_builder::UserDetailsLightBuilder;
use crate::http_server::cookies::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use actix_artcraft::sessions::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use crate::http_server::session::lookup::user_session_feature_flags::UserSessionFeatureFlags;
use crate::http_server::session::session_checker::SessionChecker;
@@ -1,7 +1,6 @@
pub mod common_requests;
pub mod common_responses;
pub mod endpoint_helpers;
pub mod cookies;
pub mod deprecated_endpoints;
pub mod endpoints;
pub mod middleware;
@@ -3,7 +3,7 @@
#![forbid(unused_mut)]
#![forbid(unused_variables)]
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_web::HttpRequest;
use log::warn;
use mysql_queries::queries::users::user_sessions::get_user_session_by_token::{get_user_session_by_token, get_user_session_by_token_pooled_connection, SessionUserRecord};
@@ -1,7 +1,7 @@
use std::error::Error;
use std::fmt::{Display, Formatter};
use actix_artcraft::sessions::http_user_session_payload_error::HttpUserSessionPayloadError;
use actix_artcraft::sessions::user_sessions::http_user_session_payload_error::HttpUserSessionPayloadError;
#[derive(Debug)]
pub enum SessionCheckerError {
@@ -21,7 +21,7 @@ use std::sync::Arc;
use std::time::Duration;
use actix::Actor;
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_cors_configs::cors::build_cors_config;
use actix_cors_configs::shared_array_buffer_cors::shared_array_buffer_cors;
use actix_helpers::middleware::banned_cidr_filter::banned_cidr_filter::BannedCidrFilter;
@@ -71,7 +71,7 @@ use crate::billing::stripe_internal_user_lookup_impl::StripeInternalUserLookupIm
use crate::configs::app_startup::redis_rate_limiters::configure_redis_rate_limiters;
use crate::configs::connect_to_database::connect_to_database;
use crate::configs::static_api_tokens::StaticApiTokenSet;
use crate::http_server::cookies::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use actix_artcraft::sessions::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use crate::http_server::middleware::error_alerting_middleware::error_alerting_middleware::ErrorAlertingMiddleware;
use crate::http_server::middleware::pushback_filter_middleware::PushbackFilter;
use crate::http_server::routes::add_routes::add_routes;
@@ -1,4 +1,4 @@
use actix_artcraft::sessions::http_user_session_manager::HttpUserSessionManager;
use actix_artcraft::sessions::user_sessions::http_user_session_manager::HttpUserSessionManager;
use actix_helpers::middleware::banned_cidr_filter::banned_cidr_set::BannedCidrSet;
use actix_helpers::middleware::banned_ip_filter::ip_ban_list::ip_ban_list::IpBanList;
use billing_artcraft_component::utils::artcraft_stripe_config::ArtcraftStripeConfigWithClient;
@@ -25,7 +25,7 @@ use url_config::third_party_url_redirector::ThirdPartyUrlRedirector;
use crate::configs::app_startup::username_set::UsernameSet;
use crate::configs::static_api_tokens::StaticApiTokenSet;
use crate::http_server::cookies::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use actix_artcraft::sessions::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager;
use crate::http_server::deprecated_endpoints::categories::tts::list_fully_computed_assigned_tts_categories::list_fully_computed_assigned_tts_categories::ModelTokensByCategoryToken;
use crate::http_server::deprecated_endpoints::leaderboard::get_leaderboard::LeaderboardInfo;
use crate::http_server::endpoints::media_files::list::list_featured_media_files_handler::ListFeaturedMediaFilesQueryParams;