Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 51s
172 lines
6.2 KiB
Diff
172 lines
6.2 KiB
Diff
From 59530d16e2938af77ab7a7e0b47a57593de5082e Mon Sep 17 00:00:00 2001
|
|
From: Fijxu <fijxu@nadeko.net>
|
|
Date: Mon, 24 Mar 2025 21:38:33 -0300
|
|
Subject: [PATCH 10/13] feat: add support for encrypted query parameters
|
|
|
|
---
|
|
src/lib/helpers/config.ts | 9 ++++
|
|
src/lib/helpers/encrypter.ts | 56 ++++++++++++++++++++
|
|
src/routes/invidious_routes/dashManifest.ts | 18 +++++--
|
|
src/routes/invidious_routes/latestVersion.ts | 14 ++++-
|
|
4 files changed, 91 insertions(+), 6 deletions(-)
|
|
create mode 100644 src/lib/helpers/encrypter.ts
|
|
|
|
diff --git a/src/lib/helpers/config.ts b/src/lib/helpers/config.ts
|
|
index a2f6be0..83ce0fa 100644
|
|
--- a/src/lib/helpers/config.ts
|
|
+++ b/src/lib/helpers/config.ts
|
|
@@ -14,6 +14,15 @@ const ConfigSchema = z.object({
|
|
max_dash_resolution: z.number().default(
|
|
Number(Deno.env.get("SERVER_MAX_DASH_RESOLUTION")),
|
|
),
|
|
+ encrypt_query_params: z
|
|
+ .boolean()
|
|
+ .default(
|
|
+ Deno.env.get("ENCRYPT_QUERY_PARAMS") === "true"
|
|
+ ? true
|
|
+ : Deno.env.get("ENCRYPT_QUERY_PARAMS") === "false"
|
|
+ ? false
|
|
+ : true,
|
|
+ ),
|
|
}).strict().default({}),
|
|
cache: z.object({
|
|
enabled: z.boolean().default(true),
|
|
diff --git a/src/lib/helpers/encrypter.ts b/src/lib/helpers/encrypter.ts
|
|
new file mode 100644
|
|
index 0000000..4b45590
|
|
--- /dev/null
|
|
+++ b/src/lib/helpers/encrypter.ts
|
|
@@ -0,0 +1,56 @@
|
|
+import { decodeBase64, encodeBase64 } from "@std/encoding/base64";
|
|
+import { Aes } from "crypto/aes.ts";
|
|
+import { Ecb, Padding } from "crypto/block-modes.ts";
|
|
+import { Config } from "./config.ts";
|
|
+
|
|
+export const encryptQuery = (
|
|
+ queryParams: string,
|
|
+ config: Config,
|
|
+): string => {
|
|
+ try {
|
|
+ const cipher = new Ecb(
|
|
+ Aes,
|
|
+ new TextEncoder().encode(config.server.secret_key.substring(0, 16)),
|
|
+ Padding.PKCS7,
|
|
+ );
|
|
+
|
|
+ const encodedData = new TextEncoder().encode(
|
|
+ queryParams,
|
|
+ );
|
|
+
|
|
+ const encryptedData = cipher.encrypt(encodedData);
|
|
+
|
|
+ return encodeBase64(encryptedData).replace(/\+/g, "-").replace(
|
|
+ /\//g,
|
|
+ "_",
|
|
+ );
|
|
+ } catch (_) {
|
|
+ return "";
|
|
+ }
|
|
+};
|
|
+
|
|
+export const decryptQuery = (
|
|
+ queryParams: string,
|
|
+ config: Config,
|
|
+): string => {
|
|
+ try {
|
|
+ const decipher = new Ecb(
|
|
+ Aes,
|
|
+ new TextEncoder().encode(config.server.secret_key.substring(0, 16)),
|
|
+ Padding.PKCS7,
|
|
+ );
|
|
+
|
|
+ const decryptedData = new TextDecoder().decode(
|
|
+ decipher.decrypt(
|
|
+ decodeBase64(
|
|
+ queryParams.replace(/-/g, "+").replace(/_/g, "/"),
|
|
+ ),
|
|
+ ),
|
|
+ );
|
|
+
|
|
+ console.log(decryptedData);
|
|
+ return decryptedData;
|
|
+ } catch (_) {
|
|
+ return "";
|
|
+ }
|
|
+};
|
|
diff --git a/src/routes/invidious_routes/dashManifest.ts b/src/routes/invidious_routes/dashManifest.ts
|
|
index 68ae21d..a4c0950 100644
|
|
--- a/src/routes/invidious_routes/dashManifest.ts
|
|
+++ b/src/routes/invidious_routes/dashManifest.ts
|
|
@@ -6,6 +6,7 @@ import {
|
|
} from "../../lib/helpers/youtubePlayerHandling.ts";
|
|
import { verifyRequest } from "../../lib/helpers/verifyRequest.ts";
|
|
import { HTTPException } from "hono/http-exception";
|
|
+import { encryptQuery } from "../../lib/helpers/encrypter.ts";
|
|
|
|
const dashManifest = new Hono();
|
|
|
|
@@ -88,14 +89,23 @@ dashManifest.get("/:videoId", async (c) => {
|
|
videoInfo.page[0].video_details?.is_post_live_dvr,
|
|
(url: URL) => {
|
|
let dashUrl = url;
|
|
+ let queryParams = dashUrl.search.substring(1) + "&host=" +
|
|
+ dashUrl.host;
|
|
+
|
|
if (local) {
|
|
- // Can't create URL type without host part
|
|
- dashUrl = config.networking.external_videoplayback_proxy +
|
|
- (dashUrl.pathname + dashUrl.search + "&host=" +
|
|
- dashUrl.host) as unknown as URL;
|
|
if (config.networking.ump) {
|
|
dashUrl = dashUrl + "&ump=1" as unknown as URL;
|
|
}
|
|
+ if (config.server.encrypt_query_params) {
|
|
+ queryParams = "enc=yes&data=" + encryptQuery(
|
|
+ queryParams,
|
|
+ config,
|
|
+ );
|
|
+ }
|
|
+ // Can't create URL type without host part
|
|
+ dashUrl = config.networking.external_videoplayback_proxy +
|
|
+ (dashUrl.pathname + "?" +
|
|
+ queryParams) as unknown as URL;
|
|
return dashUrl;
|
|
} else {
|
|
return dashUrl;
|
|
diff --git a/src/routes/invidious_routes/latestVersion.ts b/src/routes/invidious_routes/latestVersion.ts
|
|
index a8ead67..f1a7605 100644
|
|
--- a/src/routes/invidious_routes/latestVersion.ts
|
|
+++ b/src/routes/invidious_routes/latestVersion.ts
|
|
@@ -5,6 +5,7 @@ import {
|
|
youtubeVideoInfo,
|
|
} from "../../lib/helpers/youtubePlayerHandling.ts";
|
|
import { verifyRequest } from "../../lib/helpers/verifyRequest.ts";
|
|
+import { encryptQuery } from "../../lib/helpers/encrypter.ts";
|
|
|
|
const latestVersion = new Hono();
|
|
|
|
@@ -63,10 +64,19 @@ latestVersion.get("/", async (c) => {
|
|
const itagUrl = selectedItagFormat[0].url as string;
|
|
const itagUrlParsed = new URL(itagUrl);
|
|
let urlToRedirect = itagUrlParsed.toString();
|
|
+ let queryParams = itagUrlParsed.search.substring(1) + "&host=" +
|
|
+ itagUrlParsed.host;
|
|
+
|
|
if (local) {
|
|
+ if (config.server.encrypt_query_params) {
|
|
+ queryParams = "enc=yes&data=" + encryptQuery(
|
|
+ queryParams,
|
|
+ config,
|
|
+ );
|
|
+ }
|
|
+
|
|
urlToRedirect = config.networking.external_videoplayback_proxy +
|
|
- itagUrlParsed.pathname + itagUrlParsed.search +
|
|
- "&host=" + itagUrlParsed.host;
|
|
+ itagUrlParsed.pathname + "?" + queryParams;
|
|
}
|
|
|
|
if (title) urlToRedirect += `&title=${encodeURIComponent(title)}`;
|
|
--
|
|
2.49.0
|
|
|