fix: desktop client: generate PO token from user_syncid when authenticated
This commit is contained in:
parent
c34227e763
commit
1e1b0cdf45
2 changed files with 33 additions and 14 deletions
|
|
@ -293,8 +293,10 @@ struct OauthToken {
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
struct AuthCookie {
|
struct AuthCookie {
|
||||||
cookie: String,
|
cookie: String,
|
||||||
|
#[serde(alias = "account_syncid", skip_serializing_if = "Option::is_none")]
|
||||||
|
channel_syncid: Option<String>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
account_syncid: Option<String>,
|
user_syncid: Option<String>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
session_index: Option<String>,
|
session_index: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
@ -319,8 +321,9 @@ impl AuthCookie {
|
||||||
fn new(cookie: String) -> Self {
|
fn new(cookie: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cookie,
|
cookie,
|
||||||
account_syncid: None,
|
channel_syncid: None,
|
||||||
session_index: None,
|
session_index: None,
|
||||||
|
user_syncid: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1591,6 +1594,17 @@ impl RustyPipe {
|
||||||
.ok_or(Error::Auth(AuthError::NoLogin))
|
.ok_or(Error::Auth(AuthError::NoLogin))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn user_auth_datasync_id(&self) -> Result<String, Error> {
|
||||||
|
self.inner
|
||||||
|
.cache
|
||||||
|
.auth_cookie
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|c| c.user_syncid.as_ref().map(|id| id.to_owned()))
|
||||||
|
.ok_or(Error::Auth(AuthError::NoLogin))
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the user authentication cookie
|
/// Set the user authentication cookie
|
||||||
///
|
///
|
||||||
/// The cookie is used for authenticated requests with browser-based clients
|
/// The cookie is used for authenticated requests with browser-based clients
|
||||||
|
|
@ -1685,17 +1699,17 @@ impl RustyPipe {
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
// datasyncid is of the form "channel_syncid||user_syncid" for secondary channel
|
// datasyncid is of the form "channel_syncid||user_syncid" for secondary channel
|
||||||
// and just "user_syncid||" for primary channel. We only want the channel_syncid
|
// and just "user_syncid||" for primary channel.
|
||||||
let (channel_syncid, user_syncid) =
|
let (p1, p2) =
|
||||||
datasync_id
|
datasync_id
|
||||||
.split_once("||")
|
.split_once("||")
|
||||||
.ok_or(Error::Extraction(ExtractionError::InvalidData(
|
.ok_or(Error::Extraction(ExtractionError::InvalidData(
|
||||||
"datasyncId does not contain || seperator".into(),
|
"datasyncId does not contain || seperator".into(),
|
||||||
)))?;
|
)))?;
|
||||||
auth_cookie.account_syncid = if user_syncid.is_empty() {
|
(auth_cookie.channel_syncid, auth_cookie.user_syncid) = if p2.is_empty() {
|
||||||
None
|
(None, Some(p1.to_owned()))
|
||||||
} else {
|
} else {
|
||||||
Some(channel_syncid.to_owned())
|
(Some(p1.to_owned()), Some(p2.to_owned()))
|
||||||
};
|
};
|
||||||
|
|
||||||
auth_cookie.session_index = Some(
|
auth_cookie.session_index = Some(
|
||||||
|
|
@ -2129,7 +2143,7 @@ impl RustyPipeQuery {
|
||||||
if let Some(session_index) = auth_cookie.session_index {
|
if let Some(session_index) = auth_cookie.session_index {
|
||||||
r = r.header("X-Goog-AuthUser", session_index);
|
r = r.header("X-Goog-AuthUser", session_index);
|
||||||
}
|
}
|
||||||
if let Some(account_syncid) = auth_cookie.account_syncid {
|
if let Some(account_syncid) = auth_cookie.channel_syncid {
|
||||||
r = r.header("X-Goog-PageId", account_syncid);
|
r = r.header("X-Goog-PageId", account_syncid);
|
||||||
}
|
}
|
||||||
cookie = Some(auth_cookie.cookie);
|
cookie = Some(auth_cookie.cookie);
|
||||||
|
|
|
||||||
|
|
@ -139,22 +139,27 @@ impl RustyPipeQuery {
|
||||||
|
|
||||||
async fn get_player_po_token(&self, video_id: &str) -> Result<PlayerPoToken, Error> {
|
async fn get_player_po_token(&self, video_id: &str) -> Result<PlayerPoToken, Error> {
|
||||||
if let Some(bg) = &self.client.inner.botguard {
|
if let Some(bg) = &self.client.inner.botguard {
|
||||||
|
let (ident, visitor_data) = if self.opts.auth == Some(true) {
|
||||||
|
(self.client.user_auth_datasync_id()?, None)
|
||||||
|
} else {
|
||||||
let visitor_data = self.get_visitor_data(false).await?;
|
let visitor_data = self.get_visitor_data(false).await?;
|
||||||
|
(visitor_data.to_owned(), Some(visitor_data))
|
||||||
|
};
|
||||||
|
|
||||||
if bg.po_token_cache {
|
if bg.po_token_cache {
|
||||||
let session_token = self.get_session_po_token(&visitor_data).await?;
|
let session_token = self.get_session_po_token(&ident).await?;
|
||||||
Ok(PlayerPoToken {
|
Ok(PlayerPoToken {
|
||||||
visitor_data: Some(visitor_data),
|
visitor_data,
|
||||||
session_po_token: Some(session_token),
|
session_po_token: Some(session_token),
|
||||||
content_po_token: None,
|
content_po_token: None,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let (po_tokens, valid_until) =
|
let (po_tokens, valid_until) = self.get_po_tokens(&[video_id, &ident]).await?;
|
||||||
self.get_po_tokens(&[video_id, &visitor_data]).await?;
|
|
||||||
let mut po_tokens = po_tokens.into_iter();
|
let mut po_tokens = po_tokens.into_iter();
|
||||||
let po_token = po_tokens.next().unwrap();
|
let po_token = po_tokens.next().unwrap();
|
||||||
let session_po_token = po_tokens.next().unwrap();
|
let session_po_token = po_tokens.next().unwrap();
|
||||||
Ok(PlayerPoToken {
|
Ok(PlayerPoToken {
|
||||||
visitor_data: Some(visitor_data),
|
visitor_data,
|
||||||
session_po_token: Some(PoToken {
|
session_po_token: Some(PoToken {
|
||||||
po_token: session_po_token,
|
po_token: session_po_token,
|
||||||
valid_until,
|
valid_until,
|
||||||
|
|
|
||||||
Reference in a new issue