diff --git a/crates/service/web/storyteller_web/src/cookies/anonymous_visitor_tracking/avt_cookie_manager.rs b/crates/service/plugins/users/src/cookies/anonymous_visitor_tracking/avt_cookie_manager.rs similarity index 99% rename from crates/service/web/storyteller_web/src/cookies/anonymous_visitor_tracking/avt_cookie_manager.rs rename to crates/service/plugins/users/src/cookies/anonymous_visitor_tracking/avt_cookie_manager.rs index fa361a9fd8..57877b469c 100644 --- a/crates/service/web/storyteller_web/src/cookies/anonymous_visitor_tracking/avt_cookie_manager.rs +++ b/crates/service/plugins/users/src/cookies/anonymous_visitor_tracking/avt_cookie_manager.rs @@ -13,6 +13,7 @@ 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, diff --git a/crates/service/web/storyteller_web/src/cookies/anonymous_visitor_tracking/avt_cookie_payload.rs b/crates/service/plugins/users/src/cookies/anonymous_visitor_tracking/avt_cookie_payload.rs similarity index 100% rename from crates/service/web/storyteller_web/src/cookies/anonymous_visitor_tracking/avt_cookie_payload.rs rename to crates/service/plugins/users/src/cookies/anonymous_visitor_tracking/avt_cookie_payload.rs diff --git a/crates/service/web/storyteller_web/src/cookies/anonymous_visitor_tracking/mod.rs b/crates/service/plugins/users/src/cookies/anonymous_visitor_tracking/mod.rs similarity index 100% rename from crates/service/web/storyteller_web/src/cookies/anonymous_visitor_tracking/mod.rs rename to crates/service/plugins/users/src/cookies/anonymous_visitor_tracking/mod.rs diff --git a/crates/service/plugins/users/src/cookies/mod.rs b/crates/service/plugins/users/src/cookies/mod.rs index 0f135e9168..b5098c1f8d 100644 --- a/crates/service/plugins/users/src/cookies/mod.rs +++ b/crates/service/plugins/users/src/cookies/mod.rs @@ -1,2 +1,2 @@ -pub mod session_cookie_manager; -pub mod session_cookie_payload; +pub mod anonymous_visitor_tracking; +pub mod session; diff --git a/crates/service/plugins/users/src/cookies/session/mod.rs b/crates/service/plugins/users/src/cookies/session/mod.rs new file mode 100644 index 0000000000..0f135e9168 --- /dev/null +++ b/crates/service/plugins/users/src/cookies/session/mod.rs @@ -0,0 +1,2 @@ +pub mod session_cookie_manager; +pub mod session_cookie_payload; diff --git a/crates/service/plugins/users/src/cookies/session_cookie_manager.rs b/crates/service/plugins/users/src/cookies/session/session_cookie_manager.rs similarity index 97% rename from crates/service/plugins/users/src/cookies/session_cookie_manager.rs rename to crates/service/plugins/users/src/cookies/session/session_cookie_manager.rs index d35c6d2a53..7099872d58 100644 --- a/crates/service/plugins/users/src/cookies/session_cookie_manager.rs +++ b/crates/service/plugins/users/src/cookies/session/session_cookie_manager.rs @@ -13,7 +13,7 @@ use log::warn; use cookies::jwt_signer::JwtSigner; use errors::AnyhowResult; -use crate::cookies::session_cookie_payload::SessionCookiePayload; +use crate::cookies::session::session_cookie_payload::SessionCookiePayload; /** * Cookie version history @@ -136,7 +136,7 @@ impl SessionCookieManager { #[cfg(test)] mod tests { - use crate::cookies::session_cookie_manager::SessionCookieManager; + use crate::cookies::session::session_cookie_manager::SessionCookieManager; #[test] fn test_cookie_payload() { diff --git a/crates/service/plugins/users/src/cookies/session_cookie_payload.rs b/crates/service/plugins/users/src/cookies/session/session_cookie_payload.rs similarity index 100% rename from crates/service/plugins/users/src/cookies/session_cookie_payload.rs rename to crates/service/plugins/users/src/cookies/session/session_cookie_payload.rs diff --git a/crates/service/plugins/users/src/default_routes.rs b/crates/service/plugins/users/src/default_routes.rs index f75d2b79cf..10adedc13d 100644 --- a/crates/service/plugins/users/src/default_routes.rs +++ b/crates/service/plugins/users/src/default_routes.rs @@ -29,6 +29,11 @@ pub fn add_suggested_api_v1_account_creation_and_session_routes (app: App< .route(web::post().to(create_account_handler)) .route(web::head().to(|| HttpResponse::Ok())) ) + .service( + web::resource("/v1/create_account") + .route(web::post().to(create_account_handler)) + .route(web::head().to(|| HttpResponse::Ok())) + ) .service( web::resource("/login") .route(web::post().to(login_handler)) diff --git a/crates/service/plugins/users/src/endpoints/create_account_handler.rs b/crates/service/plugins/users/src/endpoints/create_account_handler.rs index 7b0bdb6681..834dcf00a7 100644 --- a/crates/service/plugins/users/src/endpoints/create_account_handler.rs +++ b/crates/service/plugins/users/src/endpoints/create_account_handler.rs @@ -21,7 +21,7 @@ use mysql_queries::queries::users::user_sessions::create_user_session::create_us use mysql_queries::tokens::Tokens; use user_input_common::check_for_slurs::contains_slurs; -use crate::cookies::session_cookie_manager::SessionCookieManager; +use crate::cookies::session::session_cookie_manager::SessionCookieManager; use crate::utils::email_to_gravatar::email_to_gravatar; use crate::validations::is_reserved_username::is_reserved_username; use crate::validations::validate_passwords::validate_passwords; diff --git a/crates/service/plugins/users/src/endpoints/login_handler.rs b/crates/service/plugins/users/src/endpoints/login_handler.rs index e959e201ed..5953d61db5 100644 --- a/crates/service/plugins/users/src/endpoints/login_handler.rs +++ b/crates/service/plugins/users/src/endpoints/login_handler.rs @@ -19,7 +19,7 @@ use mysql_queries::queries::users::user::lookup_user_for_login_by_email::lookup_ use mysql_queries::queries::users::user::lookup_user_for_login_by_username::lookup_user_for_login_by_username; use mysql_queries::queries::users::user_sessions::create_user_session::create_user_session; -use crate::cookies::session_cookie_manager::SessionCookieManager; +use crate::cookies::session::session_cookie_manager::SessionCookieManager; #[derive(Deserialize)] pub struct LoginRequest { diff --git a/crates/service/plugins/users/src/endpoints/logout_handler.rs b/crates/service/plugins/users/src/endpoints/logout_handler.rs index 72dc0ebd5f..806b525d48 100644 --- a/crates/service/plugins/users/src/endpoints/logout_handler.rs +++ b/crates/service/plugins/users/src/endpoints/logout_handler.rs @@ -14,7 +14,7 @@ use sqlx::MySqlPool; use http_server_common::response::response_error_helpers::to_simple_json_error; use mysql_queries::queries::users::user_sessions::delete_user_session::delete_user_session; -use crate::cookies::session_cookie_manager::SessionCookieManager; +use crate::cookies::session::session_cookie_manager::SessionCookieManager; #[derive(Serialize)] pub struct LogoutSuccessResponse { diff --git a/crates/service/plugins/users/src/endpoints/session_info_handler.rs b/crates/service/plugins/users/src/endpoints/session_info_handler.rs index b1ca39b83d..b671aab036 100644 --- a/crates/service/plugins/users/src/endpoints/session_info_handler.rs +++ b/crates/service/plugins/users/src/endpoints/session_info_handler.rs @@ -13,6 +13,7 @@ use sqlx::MySqlPool; use http_server_common::response::response_error_helpers::to_simple_json_error; +use crate::cookies::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager; use crate::utils::session_checker::SessionChecker; #[derive(Serialize, Copy, Clone)] @@ -109,6 +110,7 @@ pub async fn session_info_handler( http_request: HttpRequest, mysql_pool: web::Data, session_checker: web::Data, + avt_manager: web::Data, ) -> Result { let mut mysql_connection = mysql_pool.acquire() @@ -174,6 +176,18 @@ pub async fn session_info_handler( } } + let maybe_avt_cookie = match avt_manager.decode_cookie_payload_from_request(&http_request) { + Ok(Some(_avt_cookie)) => None, + _ => { + let cookie = avt_manager.make_new_cookie() + .map_err(|e| { + warn!("avt cookie creation error: {:?}", e); + SessionInfoError::ServerError + })?; + Some(cookie) + } + }; + let response = SessionInfoSuccessResponse { success: true, logged_in, @@ -183,7 +197,13 @@ pub async fn session_info_handler( let body = serde_json::to_string(&response) .map_err(|_e| SessionInfoError::ServerError)?; - Ok(HttpResponse::Ok() + let mut response_builder = HttpResponse::Ok(); + + if let Some(cookie) = maybe_avt_cookie { + response_builder.cookie(cookie); + } + + Ok(response_builder .content_type("application/json") .body(body)) } diff --git a/crates/service/plugins/users/src/utils/session_checker.rs b/crates/service/plugins/users/src/utils/session_checker.rs index bc51f816a3..e904bc8acb 100644 --- a/crates/service/plugins/users/src/utils/session_checker.rs +++ b/crates/service/plugins/users/src/utils/session_checker.rs @@ -15,7 +15,7 @@ use mysql_queries::queries::users::user_subscriptions::list_active_user_subscrip use redis_caching::redis_ttl_cache::{RedisTtlCache, RedisTtlCacheConnection}; use redis_common::redis_cache_keys::RedisCacheKeys; -use crate::cookies::session_cookie_manager::SessionCookieManager; +use crate::cookies::session::session_cookie_manager::SessionCookieManager; use crate::utils::user_session_extended::{UserSessionExtended, UserSessionPreferences, UserSessionPremiumPlanInfo, UserSessionRoleAndPermissions, UserSessionSubscriptionPlan, UserSessionUserDetails}; #[derive(Clone)] diff --git a/crates/service/web/storyteller_web/src/cookies/mod.rs b/crates/service/web/storyteller_web/src/cookies/mod.rs index c5f2dd459e..e69de29bb2 100644 --- a/crates/service/web/storyteller_web/src/cookies/mod.rs +++ b/crates/service/web/storyteller_web/src/cookies/mod.rs @@ -1 +0,0 @@ -pub mod anonymous_visitor_tracking; \ No newline at end of file diff --git a/crates/service/web/storyteller_web/src/main.rs b/crates/service/web/storyteller_web/src/main.rs index 4b9cad4a04..b4cd7b4ad8 100644 --- a/crates/service/web/storyteller_web/src/main.rs +++ b/crates/service/web/storyteller_web/src/main.rs @@ -64,7 +64,8 @@ use redis_caching::redis_ttl_cache::RedisTtlCache; use reusable_types::server_environment::ServerEnvironment; use twitch_common::twitch_secrets::TwitchSecrets; use url_config::third_party_url_redirector::ThirdPartyUrlRedirector; -use users_component::cookies::session_cookie_manager::SessionCookieManager; +use users_component::cookies::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager; +use users_component::cookies::session::session_cookie_manager::SessionCookieManager; use users_component::utils::session_checker::SessionChecker; use crate::billing::internal_product_to_stripe_lookup_impl::InternalProductToStripeLookupImpl; @@ -240,9 +241,11 @@ async fn main() -> AnyhowResult<()> { let website_homepage_redirect = easyenv::get_env_string_or_default("WEBSITE_HOMEPAGE_REDIRECT", "https://vo.codes/"); - let cookie_manager = SessionCookieManager::new(&cookie_domain, &hmac_secret); + let session_cookie_manager = SessionCookieManager::new(&cookie_domain, &hmac_secret); + let avt_cookie_manager = AvtCookieManager::new(&cookie_domain, &hmac_secret)?; + let session_checker = SessionChecker::new_with_cache( - &cookie_manager, + &session_cookie_manager, redis_ttl_cache.clone(), ); @@ -457,7 +460,8 @@ async fn main() -> AnyhowResult<()> { }, firehose_publisher, badge_granter, - cookie_manager, + avt_cookie_manager, + session_cookie_manager, session_checker, private_bucket_client, public_bucket_client, @@ -634,7 +638,8 @@ pub async fn serve(server_state: ServerState) -> AnyhowResult<()> .app_data(web::Data::new(server_state_arc.redis_pool.clone())) .app_data(web::Data::new(server_state_arc.redis_ttl_cache.clone())) .app_data(web::Data::new(server_state_arc.session_checker.clone())) - .app_data(web::Data::new(server_state_arc.cookie_manager.clone())) + .app_data(web::Data::new(server_state_arc.avt_cookie_manager.clone())) + .app_data(web::Data::new(server_state_arc.session_cookie_manager.clone())) .app_data(web::Data::new(server_state_arc.stripe.clone().config.clone())) .app_data(web::Data::new(server_state_arc.stripe.clone().client.clone())) .app_data(web::Data::new(server_state_arc.third_party_url_redirector.clone())) diff --git a/crates/service/web/storyteller_web/src/server_state.rs b/crates/service/web/storyteller_web/src/server_state.rs index 68b59ab334..fc372e4146 100644 --- a/crates/service/web/storyteller_web/src/server_state.rs +++ b/crates/service/web/storyteller_web/src/server_state.rs @@ -15,7 +15,8 @@ use mysql_queries::queries::w2l::w2l_templates::list_w2l_templates::W2lTemplateR use redis_caching::redis_ttl_cache::RedisTtlCache; use reusable_types::server_environment::ServerEnvironment; use url_config::third_party_url_redirector::ThirdPartyUrlRedirector; -use users_component::cookies::session_cookie_manager::SessionCookieManager; +use users_component::cookies::anonymous_visitor_tracking::avt_cookie_manager::AvtCookieManager; +use users_component::cookies::session::session_cookie_manager::SessionCookieManager; use users_component::utils::session_checker::SessionChecker; use crate::http_server::endpoints::categories::tts::list_fully_computed_assigned_tts_categories::list_fully_computed_assigned_tts_categories::ModelTokensByCategoryToken; @@ -58,7 +59,8 @@ pub struct ServerState { pub redis_rate_limiters: RedisRateLimiters, - pub cookie_manager: SessionCookieManager, + pub session_cookie_manager: SessionCookieManager, + pub avt_cookie_manager: AvtCookieManager, pub session_checker: SessionChecker,