Skip to content

Commit 0bb0f14

Browse files
Merge remote-tracking branch 'upstream/master' into release
2 parents a34a9ee + 3f25728 commit 0bb0f14

File tree

10 files changed

+46
-47
lines changed

10 files changed

+46
-47
lines changed

_scripts/sigFrameConfig.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ const { readFileSync } = require('fs')
55
const path = join(__dirname, '../src/renderer/sigFrameScript.js')
66
const rawScript = readFileSync(path, 'utf8')
77

8-
const script = rawScript
8+
const script = rawScript.split(/\r?\n/).map(line => line.trim()).filter(line => !line.startsWith('//')).join('')
99

1010
module.exports.sigFrameTemplateParameters = {
1111
sigFrameSrc: `data:text/html,${encodeURIComponent(`<!doctype html><script>${script}</script>`)}`,
12-
sigFrameCspHash: `sha256-${hash('sha256', script, 'base64')}`
12+
sigFrameCspHash: `sha512-${hash('sha512', script, 'base64')}`
1313
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "freetube",
33
"productName": "FreeTube",
44
"description": "A private YouTube client",
5-
"version": "0.23.10",
5+
"version": "0.23.12",
66
"license": "AGPL-3.0-or-later",
77
"main": "./dist/main.js",
88
"private": true,

src/botGuardScript.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import { BG, buildURL, GOOG_API_KEY } from 'bgutils-js'
66
/**
77
* Based on: https://github.com/LuanRT/BgUtils/blob/main/examples/node/innertube-challenge-fetcher-example.ts
88
* @param {string} videoId
9-
* @param {string} visitorData
109
* @param {import('youtubei.js').Session['context']} context
1110
*/
12-
export default async function (videoId, visitorData, context) {
11+
export default async function (videoId, context) {
1312
const requestKey = 'O43z0dpjhgX20SCx4KAo'
1413

1514
const challengeResponse = await fetch(
@@ -19,7 +18,7 @@ export default async function (videoId, visitorData, context) {
1918
headers: {
2019
Accept: '*/*',
2120
'Content-Type': 'application/json',
22-
'X-Goog-Visitor-Id': visitorData,
21+
'X-Goog-Visitor-Id': context.client.visitorData,
2322
'X-Youtube-Client-Version': context.client.clientVersion,
2423
'X-Youtube-Client-Name': '1'
2524
},
@@ -83,8 +82,5 @@ export default async function (videoId, visitorData, context) {
8382

8483
const integrityTokenBasedMinter = await BG.WebPoMinter.create({ integrityToken: response[0] }, webPoSignalOutput)
8584

86-
const contentPoToken = await integrityTokenBasedMinter.mintAsWebsafeString(videoId)
87-
const sessionPoToken = await integrityTokenBasedMinter.mintAsWebsafeString(visitorData)
88-
89-
return { contentPoToken, sessionPoToken }
85+
return await integrityTokenBasedMinter.mintAsWebsafeString(videoId)
9086
}

src/constants.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const IpcChannels = {
4747

4848
SET_INVIDIOUS_AUTHORIZATION: 'set-invidious-authorization',
4949

50-
GENERATE_PO_TOKENS: 'generate-po-tokens',
50+
GENERATE_PO_TOKEN: 'generate-po-token',
5151

5252
WRITE_SCREENSHOT: 'write-screenshot',
5353
}

src/index.ejs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@
5050
style="display: none; pointer-events: none"
5151
tabindex="-1"
5252
></iframe>
53-
<% } %>
54-
<% if (!process.env.IS_ELECTRON && !process.env.IS_ANDROID) { %>
53+
<% } else { %>
5554
<script>
5655
// This is the service worker with the Advanced caching
5756

src/main/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,8 @@ function runApp() {
891891
})
892892
})
893893

894-
ipcMain.handle(IpcChannels.GENERATE_PO_TOKENS, (_, videoId, visitorData, context) => {
895-
return generatePoToken(videoId, visitorData, context, proxyUrl)
894+
ipcMain.handle(IpcChannels.GENERATE_PO_TOKEN, (_, videoId, context) => {
895+
return generatePoToken(videoId, context, proxyUrl)
896896
})
897897

898898
ipcMain.on(IpcChannels.ENABLE_PROXY, (_, url) => {

src/main/poTokenGenerator.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,18 @@ import { readFile } from 'fs/promises'
33
import { join } from 'path'
44

55
/**
6-
* Generates a poToken (proof of origin token) using `bgutils-js`.
6+
* Generates a content-bound poToken (proof of origin token) using `bgutils-js`.
77
* The script to generate it is `src/botGuardScript.js`
88
*
99
* This is intentionally split out into it's own thing, with it's own temporary in-memory session,
1010
* as the BotGuard stuff accesses the global `document` and `window` objects and also requires making some requests.
1111
* So we definitely don't want it running in the same places as the rest of the FreeTube code with the user data.
1212
* @param {string} videoId
13-
* @param {string} visitorData
1413
* @param {string} context
1514
* @param {string|undefined} proxyUrl
16-
* @returns {Promise<{ contentPoToken: string, sessionPoToken: string }>}
15+
* @returns {Promise<string>}
1716
*/
18-
export async function generatePoToken(videoId, visitorData, context, proxyUrl) {
17+
export async function generatePoToken(videoId, context, proxyUrl) {
1918
const sessionUuid = crypto.randomUUID()
2019

2120
const theSession = session.fromPartition(`potoken-${sessionUuid}`, { cache: false })
@@ -96,7 +95,7 @@ export async function generatePoToken(videoId, visitorData, context, proxyUrl) {
9695
}
9796
})
9897

99-
const script = await getScript(videoId, visitorData, context)
98+
const script = await getScript(videoId, context)
10099

101100
const response = await webContentsView.webContents.executeJavaScript(script)
102101

@@ -110,10 +109,9 @@ let cachedScript
110109

111110
/**
112111
* @param {string} videoId
113-
* @param {string} visitorData
114112
* @param {string} context
115113
*/
116-
async function getScript(videoId, visitorData, context) {
114+
async function getScript(videoId, context) {
117115
if (!cachedScript) {
118116
const pathToScript = process.env.NODE_ENV === 'development'
119117
? join(__dirname, '../../dist/botGuardScript.js')
@@ -129,5 +127,5 @@ async function getScript(videoId, visitorData, context) {
129127
cachedScript = content.replace(match[0], `;${functionName}(FT_PARAMS)`)
130128
}
131129

132-
return cachedScript.replace('FT_PARAMS', `"${videoId}","${visitorData}",${context}`)
130+
return cachedScript.replace('FT_PARAMS', `"${videoId}",${context}`)
133131
}

src/renderer/helpers/api/local.js

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ if (process.env.SUPPORTS_LOCAL_API) {
4343
const messageId = process.env.IS_ELECTRON || crypto.randomUUID
4444
? crypto.randomUUID()
4545
: `${Date.now()}-${Math.floor(Math.random() * 10000)}`
46-
46+
4747
if (process.env.IS_ELECTRON) {
4848
const iframe = document.getElementById('sigFrame')
4949

@@ -55,15 +55,21 @@ if (process.env.SUPPORTS_LOCAL_API) {
5555
if (data.id === messageId) {
5656
window.removeEventListener('message', listener)
5757

58-
resolve(data.result)
58+
if (data.error) {
59+
reject(data.error)
60+
} else {
61+
resolve(data.result)
62+
}
5963
}
6064
}
6165
}
6266

6367
window.addEventListener('message', listener)
6468
iframe.contentWindow.postMessage(JSON.stringify({ id: messageId, code }), '*')
65-
} else {
69+
} else if (process.env.IS_ANDROID) {
6670
runDecipherScript(messageId, code).then(resolve).catch(reject)
71+
} else {
72+
reject(new Error('Please setup the eval function for the n/sig deciphering'))
6773
}
6874
})
6975
}
@@ -291,23 +297,20 @@ export async function getLocalSearchContinuation(continuationData) {
291297
export async function getLocalVideoInfo(id) {
292298
const webInnertube = await createInnertube({ withPlayer: true, generateSessionLocally: false })
293299

294-
// based on the videoId (added to the body of the /player request and to caption URLs)
300+
// based on the videoId
295301
let contentPoToken
296-
// based on the visitor data (added to the streaming URLs)
297-
let sessionPoToken
298302

299303
if (process.env.IS_ELECTRON) {
300304
const { ipcRenderer } = require('electron')
301305

302306
try {
303-
({ contentPoToken, sessionPoToken } = await ipcRenderer.invoke(
304-
IpcChannels.GENERATE_PO_TOKENS,
307+
contentPoToken = await ipcRenderer.invoke(
308+
IpcChannels.GENERATE_PO_TOKEN,
305309
id,
306-
webInnertube.session.context.client.visitorData,
307310
JSON.stringify(webInnertube.session.context)
308-
))
311+
)
309312

310-
webInnertube.session.player.po_token = sessionPoToken
313+
webInnertube.session.player.po_token = contentPoToken
311314
} catch (error) {
312315
console.error('Local API, poToken generation failed', error)
313316
throw error
@@ -414,9 +417,9 @@ export async function getLocalVideoInfo(id) {
414417
let url = info.streaming_data.dash_manifest_url
415418

416419
if (url.includes('?')) {
417-
url += `&pot=${encodeURIComponent(sessionPoToken)}&mpd_version=7`
420+
url += `&pot=${encodeURIComponent(contentPoToken)}&mpd_version=7`
418421
} else {
419-
url += `${url.endsWith('/') ? '' : '/'}pot/${encodeURIComponent(sessionPoToken)}/mpd_version/7`
422+
url += `${url.endsWith('/') ? '' : '/'}pot/${encodeURIComponent(contentPoToken)}/mpd_version/7`
420423
}
421424

422425
info.streaming_data.dash_manifest_url = url

src/renderer/sigFrameScript.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
// This is injected into the sigFrame iframe
22
// See index.ejs and webpack.renderer.config.js
33
window.addEventListener('message', (event) => {
4-
const data = JSON.parse(event.data)
4+
// eslint-disable-next-line @stylistic/semi
5+
const data = JSON.parse(event.data);
56

6-
window.parent.postMessage(JSON.stringify({
7-
id: data.id,
8-
// eslint-disable-next-line no-new-func
9-
result: new Function(data.code)()
10-
}), '*')
7+
try {
8+
window.parent.postMessage(JSON.stringify({
9+
id: data.id,
10+
// eslint-disable-next-line no-new-func
11+
result: new Function(data.code)()
12+
}), '*')
13+
} catch (error) {
14+
window.parent.postMessage(JSON.stringify({
15+
id: data.id,
16+
error
17+
}), '*')
18+
}
1119
})

yarn.lock

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8512,11 +8512,6 @@ undici-types@~6.19.2:
85128512
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
85138513
integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
85148514

8515-
undici-types@~6.20.0:
8516-
version "6.20.0"
8517-
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
8518-
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
8519-
85208515
unicode-canonical-property-names-ecmascript@^2.0.0:
85218516
version "2.0.1"
85228517
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2"

0 commit comments

Comments
 (0)