~cadence/tube-devel

cloudtube: Proxy captions via new /proxy route v1 SUPERSEDED

~lomanic
~lomanic: 1
 Proxy captions via new /proxy route

 3 files changed, 36 insertions(+), 25 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~cadence/tube-devel/patches/21806/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH cloudtube] Proxy captions via new /proxy route Export this patch

~lomanic
From: Lomanic <lomanic@hotmail.fr>

We can add more authorized paths to authorizedPaths if we need
more resources to be pulled from the NewLeaf/Invidious backend
on the same domain
---
 api/captions.js | 25 -------------------------
 api/proxy.js    | 31 +++++++++++++++++++++++++++++++
 api/video.js    |  5 +++++
 3 files changed, 36 insertions(+), 25 deletions(-)
 delete mode 100644 api/captions.js
 create mode 100644 api/proxy.js

diff --git a/api/captions.js b/api/captions.js
deleted file mode 100644
index 29611ef..0000000
--- a/api/captions.js
@@ -1,25 +0,0 @@
const fetch = require("node-fetch")
const {getUser} = require("../utils/getuser")
const constants = require("../utils/constants.js")

module.exports = [
	{
		route: `/api/v1/captions/(${constants.regex.video_id})`, methods: ["GET"], code: async ({req, fill, url}) => {
			const instanceOrigin = getUser(req).getSettingsOrDefaults().instance
			const fetchURL = new URL(`${url.pathname}${url.search}`, instanceOrigin)
			return fetch(fetchURL.toString()).then(res => {
				return res.text().then(text => {
					if (res.status === 200) {
						// Remove the position annotations that youtube unhelpfully provides
						text = text.replace(/(--> \S+).*/g, "$1")
					}
					return {
						statusCode: res.status,
						contentType: res.headers.get("content-type"),
						content: text
					}
				})
			})
		}
	}
]
diff --git a/api/proxy.js b/api/proxy.js
new file mode 100644
index 0000000..a0c8246
--- /dev/null
+++ b/api/proxy.js
@@ -0,0 +1,31 @@
const fetch = require("node-fetch")
const {getUser} = require("../utils/getuser")
const constants = require("../utils/constants.js")

// list of paths relative to the backend this route is authorized to serve
const authorizedPaths = [`/api/v1/captions/(${constants.regex.video_id})`]

module.exports = [
	{
		route: `/proxy`, methods: ["GET"], code: async ({req, fill, url}) => {
			const instanceOrigin = getUser(req).getSettingsOrDefaults().instance
			let remoteURL = url.searchParams.get("url")
			const fetchURL = new URL(remoteURL, instanceOrigin)
			if (!authorizedPaths.some(element => fetchURL.pathname.match(new RegExp(`^${element}$`)))) {
				return {
					statusCode: 401,
					content: "Unauthorized"
				}
			}
			return fetch(fetchURL.toString()).then(res => {
				return res.text().then(text => {
					return {
						statusCode: res.status,
						contentType: res.headers.get("content-type"),
						content: text
					}
				})
			})
		}
	}
]
diff --git a/api/video.js b/api/video.js
index 9ca4633..12a03dc 100644
--- a/api/video.js
+++ b/api/video.js
@@ -151,6 +151,11 @@ async function renderVideo(video, {user, settings, id, instanceOrigin}, locals =
		// rewrite description
		video.descriptionHtml = rewriteVideoDescription(video.descriptionHtml, id)

		// rewrite captions urls so they are served on the same domain via the /proxy route
		for (const caption of video.captions) {
			caption.url = "/proxy?url=" + encodeURIComponent(caption.url)
		}

		return render(200, "pug/video.pug", Object.assign(locals, {video, formats, subscribed, instanceOrigin}))
	} catch (e) {
		// show an appropriate error message
-- 
2.30.2