From a4c8eff71a6db9eb802e71d92c98b97f2a810073 Mon Sep 17 00:00:00 2001 From: jbmagination <26027089+jbmagination@users.noreply.github.com> Date: Sun, 29 Oct 2023 20:31:40 -0400 Subject: [PATCH] More work on Tor support --- .gitignore | 7 ++++-- src/core/api.js | 7 +++++- src/core/web.js | 5 ++++ src/front/cobalt.js | 15 +++++++++++- src/localization/languages/en.json | 5 ++++ src/modules/pageRender/page.js | 27 +++++++++++++++++++++- src/modules/processing/services/twitter.js | 1 - 7 files changed, 61 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index a21273d6..5419779b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # os stuff -.DS_Store -desktop.ini +**/.DS_Store +**/desktop.ini # npm node_modules @@ -24,3 +24,6 @@ docker-compose.yml # cookie file cookies.json + +# tor +tor diff --git a/src/core/api.js b/src/core/api.js index 84464b56..d21173a2 100644 --- a/src/core/api.js +++ b/src/core/api.js @@ -15,7 +15,7 @@ import { verifyStream } from "../modules/stream/manage.js"; export function runAPI(express, app, gitCommit, gitBranch, __dirname) { const corsConfig = process.env.cors === '0' ? { - origin: process.env.webURL, + origin: [process.env.webURL, process.env.webOnion], optionsSuccessStatus: 200 } : {}; @@ -49,6 +49,11 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) { const startTime = new Date(); const startTimestamp = Math.floor(startTime.getTime()); + app.use((req, res, next) => { + if (global.torEnabled && process.env.apiOnion && !(req.hostname == process.env.apiOnion)) res.setHeader('Onion-Location', `${process.env.apiOnion}${req.path}`) + next(); + }); + app.use('/api/:type', cors(corsConfig)); app.use('/api/json', apiLimiter); app.use('/api/stream', apiLimiterStream); diff --git a/src/core/web.js b/src/core/web.js index c2512c1f..e9624e1c 100644 --- a/src/core/web.js +++ b/src/core/web.js @@ -14,6 +14,11 @@ export async function runWeb(express, app, gitCommit, gitBranch, __dirname) { await buildFront(gitCommit, gitBranch); + app.use((req, res, next) => { + if (global.torEnabled && process.env.webOnion && !(req.hostname == process.env.webOnion)) res.setHeader('Onion-Location', `${process.env.webOnion}${req.path}`) + next(); + }); + app.use('/', express.static('./build/min')); app.use('/', express.static('./src/front')); diff --git a/src/front/cobalt.js b/src/front/cobalt.js index 4a3ad9e6..08c642d1 100644 --- a/src/front/cobalt.js +++ b/src/front/cobalt.js @@ -18,7 +18,8 @@ const switchers = { "dubLang": ["original", "auto"], "vimeoDash": ["false", "true"], "audioMode": ["false", "true"], - "filenamePattern": ["classic", "pretty", "basic", "nerdy"] + "filenamePattern": ["classic", "pretty", "basic", "nerdy"], + "onionPreference": ["noOnions", "onionStrict", "clearnetFallback"] }; const checkboxes = [ "alwaysVisibleButton", @@ -59,6 +60,14 @@ function sGet(id) { function sSet(id, value) { localStorage.setItem(id, value) } +if (sGet('onionPreference') == null) { + if (window.location.hostname.endsWith(".onion")) sSet("onionPreference", "clearnetFallback") + else sSet('onionPreference', 'noOnions'); +} +if (!(window.location.hostname.endsWith(".onion"))) { + document.getElementById('settings-tor').style = 'display:none;'; + if (!(sGet('onionPreference') === 'noOnions')) sSet("onionPreference", "noOnions"); +} function enable(id) { eid(id).dataset.enabled = "true"; } @@ -131,6 +140,7 @@ function detectColorScheme() { } else if (!window.matchMedia) { theme = "dark" } + if (window.location.hostname.endsWith(".onion") && theme == "auto") theme = "dark"; document.documentElement.setAttribute("data-theme", theme); } function changeTab(evnt, tabId, tabClass) { @@ -334,7 +344,9 @@ function resetSettings() { localStorage.clear(); window.location.reload(); } +if (window.location.hostname.endsWith(".onion")) document.getElementById('paste').style = "pointer-events:none;visibility:hidden;"; async function pasteClipboard() { + if (window.location.hostname.endsWith(".onion")) return try { let t = await navigator.clipboard.readText(); if (regex.test(t)) { @@ -379,6 +391,7 @@ async function download(url) { if (url.includes("youtube.com/") || url.includes("/youtu.be/")) req.vCodec = sGet("vCodec").slice(0, 4); if ((url.includes("tiktok.com/") || url.includes("douyin.com/")) && sGet("disableTikTokWatermark") === "true") req.isNoTTWatermark = true; } + if (window.location.hostname.endsWith(".onion") && !(sGet("onionPreference") == "noOnions")) req.onionPreference = sGet("onionPreference") if (sGet("disableMetadata") === "true") req.disableMetadata = true; diff --git a/src/localization/languages/en.json b/src/localization/languages/en.json index 62ef6a90..4558ec47 100644 --- a/src/localization/languages/en.json +++ b/src/localization/languages/en.json @@ -156,6 +156,11 @@ "FilenamePreviewVideoTitle": "Video Title", "FilenamePreviewAudioTitle": "Audio Title", "FilenamePreviewAudioAuthor": "Audio Author", + "Tor": "tor", + "SettingsOnionStrict": "onions only", + "SettingsClearnetFallback": "prefer onions", + "SettingsNoOnions": "no onions", + "SettingsTorDescription": "onions only: strictly uses .onions throughout entire process except where already known to be required.\nprefer onions: uses .onions throughout entire process but will fallback to clearnet if cobalt can't connect.\nno onions: will only use clearnet throughout entire process.\n\nthis setting affects twitter and reddit.", "UrgentFilenameUpdate": "customizable file names!" } } diff --git a/src/modules/pageRender/page.js b/src/modules/pageRender/page.js index c8bebc5e..ce78b321 100644 --- a/src/modules/pageRender/page.js +++ b/src/modules/pageRender/page.js @@ -38,6 +38,8 @@ export default function(obj) { audioFormats[0]["text"] = t('SettingsAudioFormatBest'); + let onionLocation = (process.env.torHost && process.env.torPort && true) && process.env.webOnion ? `` : ""; + try { return ` @@ -49,6 +51,7 @@ export default function(obj) { ${t("AppTitleCobalt")} + ${onionLocation} @@ -497,6 +500,24 @@ export default function(obj) { padding: "no-margin" }]) }) + + settingsCategory({ + name: "tor", + title: t('Tor'), + body: switcher({ + name: "onionPreference", + items: [{ + action: "onionStrict", + text: t('SettingsOnionStrict') + }, { + action: "clearnetFallback", + text: t('SettingsClearnetFallback') + }, { + action: "noOnions", + text: t('SettingsNoOnions') + }] + }) + + explanation(t('SettingsTorDescription')) + }) }] })} ${popupWithBottomButtons({ @@ -613,7 +634,11 @@ export default function(obj) {