diff --git a/crates/api_clients/artcraft/storyteller_client/src/credentials/mod.rs b/crates/api_clients/artcraft/storyteller_client/src/credentials/mod.rs index 3ea64976fa..94028babac 100644 --- a/crates/api_clients/artcraft/storyteller_client/src/credentials/mod.rs +++ b/crates/api_clients/artcraft/storyteller_client/src/credentials/mod.rs @@ -1,3 +1,4 @@ +pub mod parse_multi_cookie_header; pub mod storyteller_avt_cookie; pub mod storyteller_credential_set; pub mod storyteller_session_cookie; \ No newline at end of file diff --git a/crates/api_clients/artcraft/storyteller_client/src/credentials/parse_multi_cookie_header.rs b/crates/api_clients/artcraft/storyteller_client/src/credentials/parse_multi_cookie_header.rs new file mode 100644 index 0000000000..50630fe4ba --- /dev/null +++ b/crates/api_clients/artcraft/storyteller_client/src/credentials/parse_multi_cookie_header.rs @@ -0,0 +1,35 @@ +use crate::credentials::storyteller_avt_cookie::StorytellerAvtCookie; +use crate::credentials::storyteller_credential_set::StorytellerCredentialSet; +use crate::credentials::storyteller_session_cookie::StorytellerSessionCookie; +use cookie::Cookie; + +/// Parses a multi-cookie header string (e.g. `"visitor=abc; session=xyz"`) and extracts +/// the known Storyteller cookies by name. +/// +/// Returns `Ok(Some(...))` if at least one recognised cookie is present, +/// `Ok(None)` if the input is empty or contains no recognised cookies, +/// and `Err` if any individual cookie segment fails to parse. +pub fn parse_multi_cookie_header(header: &str) -> Result, cookie::ParseError> { + let mut avt: Option = None; + let mut session: Option = None; + + for segment in header.split(';') { + let segment = segment.trim(); + if segment.is_empty() { + continue; + } + let cookie = Cookie::parse(segment.to_owned())?; + if avt.is_none() { + avt = StorytellerAvtCookie::maybe_from_cookie(&cookie); + } + if session.is_none() { + session = StorytellerSessionCookie::maybe_from_cookie(&cookie); + } + } + + if avt.is_none() && session.is_none() { + return Ok(None); + } + + Ok(Some(StorytellerCredentialSet::initialize(avt, session))) +} diff --git a/crates/api_clients/artcraft/storyteller_client/src/credentials/storyteller_credential_set.rs b/crates/api_clients/artcraft/storyteller_client/src/credentials/storyteller_credential_set.rs index 64a26726ef..3d2d69e1e9 100644 --- a/crates/api_clients/artcraft/storyteller_client/src/credentials/storyteller_credential_set.rs +++ b/crates/api_clients/artcraft/storyteller_client/src/credentials/storyteller_credential_set.rs @@ -1,3 +1,4 @@ +use crate::credentials::parse_multi_cookie_header::parse_multi_cookie_header; use crate::credentials::storyteller_avt_cookie::StorytellerAvtCookie; use crate::credentials::storyteller_session_cookie::StorytellerSessionCookie; @@ -25,6 +26,10 @@ impl StorytellerCredentialSet { } } + pub fn parse_multi_cookie_header(header: &str) -> Result, cookie::ParseError> { + parse_multi_cookie_header(header) + } + pub fn initialize_with_just_cookie(session: StorytellerSessionCookie) -> Self { Self { avt: None, diff --git a/crates/lib/artcraft_router/tests/artcraft_seedance_2p0.rs b/crates/lib/artcraft_router/tests/artcraft_seedance_2p0.rs index c5b1aadbab..c5ae6ebc4f 100644 --- a/crates/lib/artcraft_router/tests/artcraft_seedance_2p0.rs +++ b/crates/lib/artcraft_router/tests/artcraft_seedance_2p0.rs @@ -20,9 +20,10 @@ use storyteller_client::utils::api_host::ApiHost; fn get_artcraft_client() -> RouterClient { let cookies = std::fs::read_to_string("/Users/bt/Artcraft/credentials/artcraft_cookies.txt") .expect("Failed to read /Users/bt/Artcraft/credentials/artcraft_cookies.txt"); - let credentials = StorytellerCredentialSet::initialize_with_just_cookie( - StorytellerSessionCookie::new(cookies.trim().to_string()), - ); + let cookies = cookies.trim().to_string(); + let credentials = StorytellerCredentialSet::parse_multi_cookie_header(&cookies) + .expect("Failed to parse cookies") + .expect("No credentials found"); RouterClient::Artcraft(RouterArtcraftClient::new(ApiHost::Storyteller, credentials)) }