From 7a557a97c3ebb2a46bffdb569bffabe1182154fd Mon Sep 17 00:00:00 2001
From: wukko <me@wukko.me>
Date: Fri, 23 Aug 2024 00:16:26 +0600
Subject: [PATCH] api: move service disabling to `DISABLED_SERVICES` env

---
 api/src/config.js                    | 11 +++++++++++
 api/src/core/api.js                  |  4 ++--
 api/src/processing/service-config.js | 20 --------------------
 api/src/processing/url.js            | 14 ++++++++++----
 4 files changed, 23 insertions(+), 26 deletions(-)

diff --git a/api/src/config.js b/api/src/config.js
index 2f9b9f34..bc0f68bb 100644
--- a/api/src/config.js
+++ b/api/src/config.js
@@ -1,5 +1,14 @@
+import { services } from "./processing/service-config.js";
+
 const genericUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36";
 
+const disabledServices = process.env.DISABLED_SERVICES?.split(',') || [];
+const enabledServices = new Set(Object.keys(services).filter(e => {
+    if (!disabledServices.includes(e)) {
+        return e;
+    }
+}));
+
 const env = {
     apiURL: process.env.API_URL || '',
     apiPort: process.env.API_PORT || 9000,
@@ -27,6 +36,8 @@ const env = {
     turnstileSecret: process.env.TURNSTILE_SECRET,
     jwtSecret: process.env.JWT_SECRET,
     jwtLifetime: process.env.JWT_EXPIRY || 120,
+
+    enabledServices,
 }
 
 export {
diff --git a/api/src/core/api.js b/api/src/core/api.js
index 40024156..a09b1629 100644
--- a/api/src/core/api.js
+++ b/api/src/core/api.js
@@ -203,8 +203,8 @@ export const runAPI = (express, app, __dirname) => {
         }
 
         const parsed = extract(normalizedRequest.url);
-        if (parsed === null) {
-            return fail(res, "error.api.service.unsupported");
+        if ("error" in parsed) {
+            return fail(res, `error.api.service.${parsed.error}`);
         }
 
         try {
diff --git a/api/src/processing/service-config.js b/api/src/processing/service-config.js
index eba7a6a9..816eaa1c 100644
--- a/api/src/processing/service-config.js
+++ b/api/src/processing/service-config.js
@@ -5,7 +5,6 @@ export const hlsExceptions = ["dailymotion", "vimeo", "rutube"];
 
 export const services = {
     bilibili: {
-        enabled: true,
         patterns: [
             "video/:comId",
             "_shortLink/:comShortLink",
@@ -15,11 +14,9 @@ export const services = {
         subdomains: ["m"],
     },
     dailymotion: {
-        enabled: true,
         patterns: ["video/:id"],
     },
     facebook: {
-        enabled: true,
         patterns: [
             "_shortLink/:shortLink",
             ":username/videos/:caption/:id",
@@ -31,7 +28,6 @@ export const services = {
         altDomains: ["fb.watch"],
     },
     instagram: {
-        enabled: true,
         patterns: [
             "reels/:postId",
             ":username/reel/:postId",
@@ -44,11 +40,9 @@ export const services = {
         altDomains: ["ddinstagram.com"],
     },
     loom: {
-        enabled: true,
         patterns: ["share/:id"],
     },
     ok: {
-        enabled: true,
         patterns: [
             "video/:id",
             "videoembed/:id"
@@ -56,7 +50,6 @@ export const services = {
         tld: "ru",
     },
     pinterest: {
-        enabled: true,
         patterns: [
             "pin/:id",
             "pin/:id/:garbage",
@@ -64,7 +57,6 @@ export const services = {
         ],
     },
     reddit: {
-        enabled: true,
         patterns: [
             "r/:sub/comments/:id/:title",
             "user/:user/comments/:id/:title"
@@ -72,7 +64,6 @@ export const services = {
         subdomains: "*",
     },
     rutube: {
-        enabled: true,
         patterns: [
             "video/:id",
             "play/embed/:id",
@@ -84,7 +75,6 @@ export const services = {
         tld: "ru",
     },
     snapchat: {
-        enabled: true,
         patterns: [
             ":shortLink",
             "spotlight/:spotlightId",
@@ -97,7 +87,6 @@ export const services = {
         subdomains: ["t", "story"],
     },
     soundcloud: {
-        enabled: true,
         patterns: [
             ":author/:song/s-:accessKey",
             ":author/:song",
@@ -106,7 +95,6 @@ export const services = {
         subdomains: ["on", "m"],
     },
     streamable: {
-        enabled: true,
         patterns: [
             ":id",
             "o/:id",
@@ -115,7 +103,6 @@ export const services = {
         ],
     },
     tiktok: {
-        enabled: true,
         patterns: [
             ":user/video/:postId",
             ":id",
@@ -126,7 +113,6 @@ export const services = {
         subdomains: ["vt", "vm", "m"],
     },
     tumblr: {
-        enabled: true,
         patterns: [
             "post/:id",
             "blog/view/:user/:id",
@@ -136,12 +122,10 @@ export const services = {
         subdomains: "*",
     },
     twitch: {
-        enabled: true,
         patterns: [":channel/clip/:clip"],
         tld: "tv",
     },
     twitter: {
-        enabled: true,
         patterns: [
             ":user/status/:id",
             ":user/status/:id/video/:index",
@@ -153,12 +137,10 @@ export const services = {
         altDomains: ["x.com", "vxtwitter.com", "fixvx.com"],
     },
     vine: {
-        enabled: true,
         patterns: ["v/:id"],
         tld: "co",
     },
     vimeo: {
-        enabled: true,
         patterns: [
             ":id",
             "video/:id",
@@ -168,7 +150,6 @@ export const services = {
         subdomains: ["player"],
     },
     vk: {
-        enabled: true,
         patterns: [
             "video:userId_:videoId",
             "clip:userId_:videoId",
@@ -177,7 +158,6 @@ export const services = {
         subdomains: ["m"],
     },
     youtube: {
-        enabled: true,
         patterns: [
             "watch?v=:id",
             "embed/:id",
diff --git a/api/src/processing/url.js b/api/src/processing/url.js
index a9313e25..d9520eee 100644
--- a/api/src/processing/url.js
+++ b/api/src/processing/url.js
@@ -1,6 +1,8 @@
-import { services } from "./service-config.js";
-import { strict as assert } from "node:assert";
 import psl from "psl";
+import { strict as assert } from "node:assert";
+
+import { env } from "../config.js";
+import { services } from "./service-config.js";
 
 function aliasURL(url) {
     assert(url instanceof URL);
@@ -160,8 +162,12 @@ export function extract(url) {
 
     const host = getHostIfValid(url);
 
-    if (!host || !services[host].enabled) {
-        return null;
+    if (!host) {
+        return { error: "unsupported" };
+    }
+
+    if (!env.enabledServices.has(host)) {
+        return { error: "disabled" };
     }
 
     let patternMatch;