From 3e9868fd5e8f8cd253c3aaeca869e102b33c9e54 Mon Sep 17 00:00:00 2001 From: teddit Date: Sun, 21 Mar 2021 21:14:11 +0100 Subject: [PATCH] replace youtube/twitter/instagram with privacy respecting ones --- config.js.template | 6 -- inc/commons.js | 49 +++++++++++---- inc/processJsonPost.js | 2 +- inc/processJsonSubreddit.js | 2 +- inc/processJsonUser.js | 4 +- inc/processSearchResults.js | 2 +- inc/processSubredditsExplore.js | 2 +- routes.js | 10 +++ static/css/styles.css | 7 +-- views/includes/head.pug | 3 + views/index.pug | 2 +- views/preferences.pug | 106 +++++++++++++++++++------------- views/subreddit.pug | 6 +- 13 files changed, 124 insertions(+), 77 deletions(-) diff --git a/config.js.template b/config.js.template index 4c2c760..9c6ae4e 100644 --- a/config.js.template +++ b/config.js.template @@ -55,12 +55,6 @@ const config = { new_page: 60 }, }, - convert_urls: { - /** - * When enabled, all the domains in the content (e.g. comments, sidebars, wikis etc.) will be replaced with a privacy respecting version. - */ - reddit: true, // old.reddit.com and reddit.com --> instance domain (config.domain) - }, valid_media_domains: ['preview.redd.it', 'external-preview.redd.it', 'i.redd.it', 'v.redd.it', 'a.thumbs.redditmedia.com', 'b.thumbs.redditmedia.com', 'emoji.redditmedia.com', 'thumbs.gfycat.com', 'i.ytimg.com'], valid_embed_video_domains: ['gfycat.com', 'youtube.com'], reddit_api_error_text: `Seems like your instance is either blocked (e.g. due to API rate limiting), reddit is currently down, or your API key is expired and not renewd properly. This can also happen for other reasons.` diff --git a/inc/commons.js b/inc/commons.js index 5d7d637..92db793 100644 --- a/inc/commons.js +++ b/inc/commons.js @@ -130,7 +130,9 @@ module.exports = function(request, fs) { return d.toUTCString() } - this.unescape = (s) => { + + + this.unescape = (s, user_preferences) => { /* It would make much more sense to rename this function to something * like "formatter". */ @@ -148,23 +150,44 @@ module.exports = function(request, fs) { '"': '"', '"': '"' } - if(config.convert_urls.reddit) { - let str = s.replace(re, (m) => { - return unescaped[m] - }) - let r = /([A-z.]+\.)?(reddit(\.com)|redd(\.it))/gm; - let result = str.replace(r, config.domain) - return result - } else { - return s.replace(re, (m) => { - return unescaped[m] - }) - } + let result = s.replace(re, (m) => { + return unescaped[m] + }) + + result = replacePrivacyDomains(result, user_preferences) + + return result } else { return '' } } + this.replacePrivacyDomains = (str, user_preferences) => { + if(typeof(user_preferences) == 'undefined') + return str + + let redditRegex = /([A-z.]+\.)?(reddit(\.com)|redd(\.it))/gm; + let youtubeRegex = /([A-z.]+\.)?youtu(be\.com|\.be)/gm; + let twitterRegex = /([A-z.]+\.)?twitter\.com/gm; + let instagramRegex = /([A-z.]+\.)?instagram.com/gm; + + str = str.replace(redditRegex, config.domain) + + if(typeof(user_preferences.domain_youtube) != 'undefined') + if(user_preferences.domain_youtube) + str = str.replace(youtubeRegex, user_preferences.domain_youtube) + + if(typeof(user_preferences.domain_twitter) != 'undefined') + if(user_preferences.domain_twitter) + str = str.replace(twitterRegex, user_preferences.domain_twitter) + + if(typeof(user_preferences.domain_instagram) != 'undefined') + if(user_preferences.domain_instagram) + str = str.replace(instagramRegex, user_preferences.domain_instagram) + + return str + } + this.deleteFiles = (files, callback) => { var i = files.length files.forEach((filepath) => { diff --git a/inc/processJsonPost.js b/inc/processJsonPost.js index 8d3ebf0..bfb172a 100644 --- a/inc/processJsonPost.js +++ b/inc/processJsonPost.js @@ -24,7 +24,7 @@ module.exports = function(fetch) { over_18: post.over_18, permalink: teddifyUrl(post.permalink), title: post.title, - url: teddifyUrl(post.url), + url: teddifyUrl(post.url, user_preferences), ups: post.ups, id: post.id, domain: post.domain, diff --git a/inc/processJsonSubreddit.js b/inc/processJsonSubreddit.js index b73f94d..aa2a2ec 100644 --- a/inc/processJsonSubreddit.js +++ b/inc/processJsonSubreddit.js @@ -91,7 +91,7 @@ module.exports = function() { title: data.title, ups: data.ups, upvote_ratio: data.upvote_ratio, - url: data.url, + url: replacePrivacyDomains(data.url, user_preferences), stickied: data.stickied, is_self_link: is_self_link, subreddit_front: subreddit_front, diff --git a/inc/processJsonUser.js b/inc/processJsonUser.js index f80ed78..e89300f 100644 --- a/inc/processJsonUser.js +++ b/inc/processJsonUser.js @@ -64,7 +64,7 @@ module.exports = function() { title: post.title, created: post.created_utc, ups: post.ups, - url: url, + url: replacePrivacyDomains(url, user_preferences), thumbnail: await downloadAndSave(post.thumbnail), duration: duration, edited: post.edited, @@ -83,7 +83,7 @@ module.exports = function() { created: post.created_utc, subreddit_name_prefixed: post.subreddit_name_prefixed, ups: post.ups, - url: url, + url: replacePrivacyDomains(url, user_preferences), edited: post.edited, body_html: unescape(post.body_html), num_comments: post.num_comments, diff --git a/inc/processSearchResults.js b/inc/processSearchResults.js index 945c9c8..5e4b7da 100644 --- a/inc/processSearchResults.js +++ b/inc/processSearchResults.js @@ -72,7 +72,7 @@ module.exports = function() { link_flair_text: post.link_flair_text, ups: post.ups, images: images, - url: post.url, + url: replacePrivacyDomains(post.url, user_preferences), edited: post.edited, selftext_html: unescape(post.body_html), num_comments: post.num_comments, diff --git a/inc/processSubredditsExplore.js b/inc/processSubredditsExplore.js index 894f196..f01792f 100644 --- a/inc/processSubredditsExplore.js +++ b/inc/processSubredditsExplore.js @@ -36,7 +36,7 @@ module.exports = function() { display_name: data.display_name, display_name_prefixed: data.display_name_prefixed, public_description: data.public_description, - url: data.url, + url: replacePrivacyDomains(data.url, user_preferences), subscribers: data.subscribers, over_18: data.over18, title: data.title, diff --git a/routes.js b/routes.js index 3c658c3..460740f 100644 --- a/routes.js +++ b/routes.js @@ -1598,6 +1598,9 @@ module.exports = (app, redis, fetch, RedditAPI) => { let post_media_max_height = req.body.post_media_max_height let collapse_child_comments = req.body.collapse_child_comments let show_upvoted_percentage = req.body.show_upvoted_percentage + let domain_twitter = req.body.domain_twitter + let domain_youtube = req.body.domain_youtube + let domain_instagram = req.body.domain_instagram res.cookie('theme', theme, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) @@ -1634,6 +1637,10 @@ module.exports = (app, redis, fetch, RedditAPI) => { show_upvoted_percentage = 'false' res.cookie('show_upvoted_percentage', show_upvoted_percentage, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) + res.cookie('domain_twitter', domain_twitter, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) + res.cookie('domain_youtube', domain_youtube, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) + res.cookie('domain_instagram', domain_instagram, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) + return res.redirect('/preferences') }) @@ -1776,6 +1783,9 @@ module.exports = (app, redis, fetch, RedditAPI) => { res.clearCookie('collapse_child_comments') res.clearCookie('show_upvoted_percentage') res.clearCookie('subbed_subreddits') + res.clearCookie('domain_twitter') + res.clearCookie('domain_youtube') + res.clearCookie('domain_instagram') } } diff --git a/static/css/styles.css b/static/css/styles.css index 060804c..9716b1f 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -150,14 +150,11 @@ form .setting { margin: 10px 0; width: 100%; } -.export-import-form { - margin: 60px 0px 0px 0px; -} .export-import-form input { margin: 10px 0px 10px 0px; } -.export-import-form:last-child { - margin: 25px 0px 15px 0px; +.bottom-prefs { + margin: 60px 0px 0px 0px; } .container .content small.notice { padding-top: 20px; diff --git a/views/includes/head.pug b/views/includes/head.pug index 19c0854..5939076 100644 --- a/views/includes/head.pug +++ b/views/includes/head.pug @@ -8,6 +8,9 @@ link(rel="stylesheet", type="text/css", href="/css/styles.css") link(rel="icon", type="image/png", sizes="32x32", href="/favicon.png") meta(name="viewport", content="width=device-width, initial-scale=1.0") - + if(!user_preferences) + user_preferences = {} + function kFormatter(num) { return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000).toFixed(1)) + 'k' : Math.sign(num)*Math.abs(num) } diff --git a/views/index.pug b/views/index.pug index dede57d..dddf000 100644 --- a/views/index.pug +++ b/views/index.pug @@ -109,7 +109,7 @@ html .line .line .selftext - != unescape(link.selftext_html) + != unescape(link.selftext_html, user_preferences) if (link.images && link.images.preview) style. details.preview-container img { diff --git a/views/preferences.pug b/views/preferences.pug index 1321155..252859a 100644 --- a/views/preferences.pug +++ b/views/preferences.pug @@ -9,6 +9,25 @@ html .content h1 Preferences form(action="/saveprefs", method="POST") + legend Privacy + .setting + label(for="domain_twitter") Replace Twitter links with Nitter (blank to disable): + if(user_preferences.domain_twitter != '' && typeof(user_preferences.domain_twitter) != 'undefined') + input(type="text", name="domain_twitter", id="domain_twitter", value="" + user_preferences.domain_twitter + "", placeholder="e.g. nitter.net") + else + input(type="text", name="domain_twitter", id="domain_twitter", placeholder="e.g. nitter.net") + .setting + label(for="domain_youtube") Replace YouTube links with Invidious (blank to disable): + if(user_preferences.domain_youtube != '' && typeof(user_preferences.domain_youtube) != 'undefined') + input(type="text", name="domain_youtube", id="domain_youtube", value="" + user_preferences.domain_youtube + "", placeholder="e.g. invidious.site") + else + input(type="text", name="domain_youtube", id="domain_youtube", placeholder="e.g. invidious.site") + .setting + label(for="domain_instagram") Replace Instagram links with Bibliogram (blank to disable): + if(user_preferences.domain_instagram != '' && typeof(user_preferences.domain_instagram) != 'undefined') + input(type="text", name="domain_instagram", id="domain_instagram", value="" + user_preferences.domain_instagram + "", placeholder="e.g. bibliogram.art") + else + input(type="text", name="domain_instagram", id="domain_instagram", placeholder="e.g. bibliogram.art") legend Display .setting label(for="theme") Theme: @@ -77,7 +96,11 @@ html input(type="checkbox", name="show_upvoted_percentage", id="show_upvoted_percentage", checked="checked") else input(type="checkbox", name="show_upvoted_percentage", id="show_upvoted_percentage") - legend Subscribed subreddits + small(class="notice") Preferences are stored client-side using cookies without any personal information. + br + input(type="submit", value="Save preferences") + a(href="/resetprefs", class="btn") Reset preferences + .bottom-prefs .setting details summary @@ -90,51 +113,48 @@ html a(href="/r/" + subreddit) #{subreddit} else small no subscribed subreddits - small(class="notice") Preferences are stored client-side using cookies without any personal information. - input(type="submit", value="Save preferences") - a(href="/resetprefs", class="btn") Reset preferences - form(action="/export_prefs", method="POST", class="export-import-form") - if preferences_key - details(open) - summary - span Export preferences - .setting - small By exporting your preferences you can transfer your subscribed subreddits and preferences to another device. Or you could create a bookmark if you tend to delete your cookies frequently. - br - label(for="export_saved") Export saved posts: - input(type="checkbox", name="export_saved", id="export_saved") - br - input(type="submit", value="Export preferences") - if preferences_key - - var protocol = 'http' - if instance_config.https_enabled === true - - var protocol = 'https' - p Visit this URL to import your preferences: - a(href=`${protocol}://${instance_config.domain}/import_prefs/${preferences_key}`) #{protocol}://#{instance_config.domain}/import_prefs/#{preferences_key} - else + form(action="/export_prefs", method="POST", class="export-import-form") + if preferences_key + details(open) + summary + span Export preferences + .setting + small By exporting your preferences you can transfer your subscribed subreddits and preferences to another device. Or you could create a bookmark if you tend to delete your cookies frequently. + br + label(for="export_saved") Export saved posts: + input(type="checkbox", name="export_saved", id="export_saved") + br + input(type="submit", value="Export preferences") + if preferences_key + - var protocol = 'http' + if instance_config.https_enabled === true + - var protocol = 'https' + p Visit this URL to import your preferences: + a(href=`${protocol}://${instance_config.domain}/import_prefs/${preferences_key}`) #{protocol}://#{instance_config.domain}/import_prefs/#{preferences_key} + else + details + summary + span Export preferences + .setting + small By exporting your preferences you can transfer your subscribed subreddits and preferences to another device. Or you could create a bookmark if you tend to delete your cookies frequently. + br + small If you are exporting to a file, please save your preferences first! + br + label(for="export_saved") Export saved posts: + input(type="checkbox", name="export_saved", id="export_saved") + br + label(for="export_to_file") Export preferences to a JSON file: + input(type="checkbox", name="export_to_file", id="export_to_file") + br + input(type="submit", value="Export preferences") + form(action="/import_prefs", method="POST", class="export-import-form", enctype="multipart/form-data") details summary - span Export preferences + span Import JSON preferences file .setting - small By exporting your preferences you can transfer your subscribed subreddits and preferences to another device. Or you could create a bookmark if you tend to delete your cookies frequently. + small All your current preferences and saved posts will be reseted and the settings from the JSON file will be used instead. br - small If you are exporting to a file, please save your preferences first! + input(type="file", name="file", id="file") br - label(for="export_saved") Export saved posts: - input(type="checkbox", name="export_saved", id="export_saved") - br - label(for="export_to_file") Export preferences to a JSON file: - input(type="checkbox", name="export_to_file", id="export_to_file") - br - input(type="submit", value="Export preferences") - form(action="/import_prefs", method="POST", class="export-import-form", enctype="multipart/form-data") - details - summary - span Import JSON preferences file - .setting - small All your current preferences and saved posts will be reseted and the settings from the JSON file will be used instead. - br - input(type="file", name="file", id="file") - br - input(type="submit", value="Import preferences") + input(type="submit", value="Import preferences") include includes/footer.pug diff --git a/views/subreddit.pug b/views/subreddit.pug index 1acba65..20778c8 100644 --- a/views/subreddit.pug +++ b/views/subreddit.pug @@ -135,7 +135,7 @@ html .line .line .selftext - != unescape(link.selftext_html) + != unescape(link.selftext_html, user_preferences) if (link.images && link.images.preview) style. details.preview-container img { @@ -215,9 +215,9 @@ html .heading p.title #{subreddit_about.title} .short-description - != unescape(subreddit_about.public_description_html) + != unescape(subreddit_about.public_description_html, user_preferences) .description - != unescape(subreddit_about.description_html) + != unescape(subreddit_about.description_html, user_preferences) else if subreddit.includes('+') .content