diff --git a/crates/api_clients/grok_client/src/error/grok_client_error.rs b/crates/api_clients/grok_client/src/error/grok_client_error.rs index 6c1b52157..b33f90255 100644 --- a/crates/api_clients/grok_client/src/error/grok_client_error.rs +++ b/crates/api_clients/grok_client/src/error/grok_client_error.rs @@ -47,6 +47,18 @@ pub enum GrokClientError { /// Our script logic is out of date ScriptLogicOutOfDate, + /// Our script logic is out of date (SVG) + ScriptSvgLogicOutOfDate, + + /// Our script logic is out of date (script 1) + Script1LogicOutOfDate, + + /// Our script logic is out of date (script 2) + Script2LogicOutOfDate, + + /// Our script logic is out of date (xsid script) + ScriptXsidLogicOutOfDate, + /// Signature algorithm isn't working with inputs BadSignatureInputs, @@ -115,6 +127,10 @@ impl Display for GrokClientError { Self::FailedToDecodeVerificationToken(err) => write!(f, "Failed to decode verification token: {}", err), Self::InvalidVerificationTokenBytes => write!(f, "Invalid verification token bytes"), Self::ScriptLogicOutOfDate => write!(f, "Script logic out of date"), + Self::ScriptSvgLogicOutOfDate => write!(f, "Script logic out of date (SVG parsing)"), + Self::Script1LogicOutOfDate => write!(f, "Script logic out of date (script 1)"), + Self::Script2LogicOutOfDate => write!(f, "Script logic out of date (script 2)"), + Self::ScriptXsidLogicOutOfDate => write!(f, "Script logic out of date (xsid script)"), Self::BadSignatureInputs => write!(f, "Bad signature inputs"), Self::TimeoutMathBroken => write!(f, "Timeout math is broken"), Self::NoCookiesPresent => write!(f, "No cookies present"), diff --git a/crates/api_clients/grok_client/src/requests/index_page/parsers/script/parse_script_actions_and_xsid_script_path.rs b/crates/api_clients/grok_client/src/requests/index_page/parsers/script/parse_script_actions_and_xsid_script_path.rs index ae7fafa55..bd383bc1f 100644 --- a/crates/api_clients/grok_client/src/requests/index_page/parsers/script/parse_script_actions_and_xsid_script_path.rs +++ b/crates/api_clients/grok_client/src/requests/index_page/parsers/script/parse_script_actions_and_xsid_script_path.rs @@ -2,14 +2,17 @@ use crate::error::grok_client_error::GrokClientError; use once_cell::sync::Lazy; use regex::Regex; use std::collections::HashMap; +use log::info; static ACTIONS_REGEX : Lazy = Lazy::new(|| { Regex::new(r#"createServerReference\)\("([a-f0-9]+)""#) .expect("Regex should parse") }); +/// 2025-10-01: "(static/chunks/[^"]+\.js)"[^}]*?a\(880932\)" +/// 2025-12-01: "(static/chunks/[^"]+\.js)"[^}]*?\(880932\)" static XSID_SCRIPT_REGEX : Lazy = Lazy::new(|| { - Regex::new(r#""(static/chunks/[^"]+\.js)"[^}]*?a\(880932\)"#) + Regex::new(r#""(static/chunks/[^"]+\.js)"[^}]*?\(880932\)"#) .expect("Regex should parse") }); @@ -36,33 +39,32 @@ pub fn parse_script_actions_and_xsid_script_path(scripts: &HashMap action_script_path, - None => return Err(GrokClientError::ScriptLogicOutOfDate), - }; + // NB: Commented out because we don't use it. + // let action_script_path = match action_script_path { + // Some(action_script_path) => action_script_path, + // None => return Err(GrokClientError::ScriptLogicOutOfDate), + // }; let script_content_1 = match script_content_1 { Some(script_content_1) => script_content_1, - None => return Err(GrokClientError::ScriptLogicOutOfDate), + None => return Err(GrokClientError::Script1LogicOutOfDate), }; let script_content_2 = match script_content_2 { Some(script_content_2) => script_content_2, - None => return Err(GrokClientError::ScriptLogicOutOfDate), + None => return Err(GrokClientError::Script2LogicOutOfDate), }; + //println!("Script content 1:"); + //println!("{}", script_content_1); + //println!("Script content 2:"); + //println!("{}", script_content_2); + let actions = ACTIONS_REGEX.captures_iter(&script_content_1) .flat_map(|captures| captures.get(1).map(|m| m.as_str().to_string())) .collect::>(); - let xsid_script_path = XSID_SCRIPT_REGEX.captures(&script_content_2) - .map(|captures| captures.get(1).map(|m| m.as_str().to_string())) - .flatten(); - - let xsid_script_path = match xsid_script_path { - Some(xsid_script) => xsid_script, - None => return Err(GrokClientError::ScriptLogicOutOfDate), - }; + let xsid_script_path = parse_xsid_script_path_from_turbopack_script(&script_content_2)?; Ok(ActionsAndXsid { actions, @@ -70,10 +72,23 @@ pub fn parse_script_actions_and_xsid_script_path(scripts: &HashMap Result { + let xsid_script_path = XSID_SCRIPT_REGEX.captures(&script_source) + .map(|captures| captures.get(1) + .map(|m| m.as_str() + .to_string())) + .flatten(); + + match xsid_script_path { + Some(xsid_script) => Ok(xsid_script), + None => Err(GrokClientError::ScriptXsidLogicOutOfDate), + } +} + #[cfg(test)] mod tests { use crate::requests::index_page::get_index_page_and_scripts::{get_index_page_and_scripts, GetIndexPageAndScriptsArgs}; - use crate::requests::index_page::parsers::script::parse_script_actions_and_xsid_script_path::parse_script_actions_and_xsid_script_path; + use crate::requests::index_page::parsers::script::parse_script_actions_and_xsid_script_path::{parse_script_actions_and_xsid_script_path, parse_xsid_script_path_from_turbopack_script}; use crate::test_utils::get_test_cookies::get_test_cookies; use errors::AnyhowResult; @@ -93,4 +108,17 @@ mod tests { assert_eq!(1, 2); Ok(()) } + + #[test] + fn parse_turbopack_script_2_for_xsid() { + // NB: The XSID parsing script broke on December 1st. + // The valid script to parse out is "static/chunks/6450f465e55b5c24.js" (as it contains the magic numbers). This comes before the string (880932) + // They probably just changed the TurboPack configs. + let example_script_2 = r#" + (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,483347,a=>{a.v(s=>Promise.all(["static/chunks/6450f465e55b5c24.js"].map(s=>a.l(s))).then(()=>s(880932)))},330040,a=>{a.v(s=>Promise.all(["static/chunks/5cc0fc78839e38d4.js"].map(s=>a.l(s))).then(()=>s(921398)))},127660,a=>{a.v(s=>Promise.all(["static/chunks/fc24fa4ac57f0fa9.js"].map(s=>a.l(s))).then(()=>s(969999)))},307492,a=>{a.v(s=>Promise.all(["static/chunks/eb46b9f393cc69d9.js"].map(s=>a.l(s))).then(()=>s(529107)))},460973,a=>{a.v(s=>Promise.all(["static/chunks/7ff9ad06da182f94.js"].map(s=>a.l(s))).then(()=>s(296273)))},900864, + "#; + + let parsed = parse_xsid_script_path_from_turbopack_script(example_script_2).unwrap(); + assert_eq!(parsed, "static/chunks/6450f465e55b5c24.js".to_string()); + } } diff --git a/crates/api_clients/grok_client/src/requests/index_page/utils/select_svg_path_by_loading_anim.rs b/crates/api_clients/grok_client/src/requests/index_page/utils/select_svg_path_by_loading_anim.rs index 3603f82d2..999700cf0 100644 --- a/crates/api_clients/grok_client/src/requests/index_page/utils/select_svg_path_by_loading_anim.rs +++ b/crates/api_clients/grok_client/src/requests/index_page/utils/select_svg_path_by_loading_anim.rs @@ -11,7 +11,7 @@ pub fn select_svg_path_by_loading_anim( .map(|path| path.clone()) .ok_or_else(|| { error!("There was not an SVG path data at index {} (array len {})", loading_anim.0, svg_paths.len()); - GrokClientError::ScriptLogicOutOfDate + GrokClientError::ScriptSvgLogicOutOfDate }) }