This commit is contained in:
QuiteAFancyEmerald 2024-07-08 07:28:25 -07:00
commit 1d36f0a438
9 changed files with 198 additions and 88 deletions

View file

@ -201,7 +201,7 @@ This is an example of DNS records involving Heroku. Self-hosting will require `A
As stated previously, Holy Unblocker is hosted locally with Ultraviolet. As stated previously, Holy Unblocker is hosted locally with Ultraviolet.
#### Freenom/Domain Steps #### Freenom/Domain Steps
For beginners, Freenom is a good provider for obtaining domains for free. However the catch is that you can only use properly "Freenom" domains for free being .cf, .ml, .gq, ga and .tk. However these can be blocked rather easily. For beginners, Freenom is a good provider for obtaining domains for free. However, Freenom only provides their TLDs (`.cf`, `.ml`, `.gq`, `.ga`, and `.tk`) for free, which can be easily blocked.
- Get some Freenom domains then add them to your Heroku instance (Personal > [App Name] > Settings > Domains) - Get some Freenom domains then add them to your Heroku instance (Personal > [App Name] > Settings > Domains)
Add a domain for both `www.example.cf` and `example.cf` with .cf being interchangeable with other Freenom domain names. Add a domain for both `www.example.cf` and `example.cf` with .cf being interchangeable with other Freenom domain names.

View file

@ -6,22 +6,21 @@ export { insertText, paintSource, tryReadFile };
/* /*
// Try this instead of the .replace method. Might be more performant. // Try this instead of the .replace method. Might be more performant.
// Will edit str by replacing all matches of lis with newText. // Will edit str by replacing all matches of lis with newText.
// Usage: insertText(["<Example1>", "<Example2>"], // Usage: insertText(['<Example1>', '<Example2>'],
// "<Example1> Big Giant Paragraph <Example2> Smol Paragraph", // '<Example1> Big Giant Paragraph <Example2> Smol Paragraph',
// stringOrFunctionToGenerateNewText); // stringOrFunctionToGenerateNewText);
*/ */
const insertText = (lis, str, newText) => { const insertText = (lis, str, newText) => {
// The lis argument should be a list of strings containing placeholders.
// This will put other relevant argument types, like a string, into a list.
lis = [].concat(lis);
let position; let position;
// Loop through each of the placeholder strings.
for (let placeholder of lis) { // The lis argument should be a list of strings containing placeholders.
// Ensure lis is formatted as a list, and loop through each of the
// placeholder strings.
for (let placeholder of [].concat(lis)) {
// Find all matches of a placeholder string and insert new text there. // Find all matches of a placeholder string and insert new text there.
while ((position = str.indexOf(placeholder)) >= 0) while ((position = str.indexOf(placeholder)) >= 0)
str = str.slice(0, position) str = str.slice(0, position)
+ (typeof newText == "function" ? newText() : newText) + (typeof newText == 'function' ? newText() : newText)
+ str.slice(position + placeholder.length); + str.slice(position + placeholder.length);
} }
return str; return str;
@ -34,7 +33,7 @@ const insertText = (lis, str, newText) => {
// changes with each time it is loaded. // changes with each time it is loaded.
const randomListItem = lis => () => lis[Math.random() * lis.length | 0], const randomListItem = lis => () => lis[Math.random() * lis.length | 0],
charset = ["&#173;", "&#8203;", "&shy;", "<wbr>"], charset = ['&#173;', '&#8203;', '&shy;', '<wbr>'],
getRandomChar = randomListItem(charRandom), getRandomChar = randomListItem(charRandom),
insertCharset = str => insertText( insertCharset = str => insertText(
charset, charset,
@ -44,14 +43,14 @@ insertCharset = str => insertText(
getRandomSplash = randomListItem(splashRandom), getRandomSplash = randomListItem(splashRandom),
hutaoInsert = str => insertText( hutaoInsert = str => insertText(
"<!--HUTAOWOA-->", '<!--HUTAOWOA-->',
str, str,
getRandomSplash getRandomSplash
), ),
getCookingText = () => `<span style="display:none" data-fact="${randomListItem(vegetables)()}">${randomListItem(cookingInserts)()}</span>`, getCookingText = () => `<span style="display:none" data-fact="${randomListItem(vegetables)()}">${randomListItem(cookingInserts)()}</span>`,
insertCooking = str => insertText( insertCooking = str => insertText(
"<!-- IMPORTANT-HUTAOCOOKINGINSERT-DONOTDELETE -->", '<!-- IMPORTANT-HUTAOCOOKINGINSERT-DONOTDELETE -->',
str, str,
getCookingText getCookingText
), ),
@ -67,7 +66,7 @@ cacheBusting = str => {
paintSource = str => insertCharset(hutaoInsert(insertCooking(cacheBusting(str)))), paintSource = str => insertCharset(hutaoInsert(insertCooking(cacheBusting(str)))),
// Grabs the text content of a file. // Grabs the text content of a file.
tryReadFile = file => existsSync(file) ? readFileSync(file, "utf8") : text404; tryReadFile = file => existsSync(file) ? readFileSync(file, 'utf8') : text404;
/* /*
// All of this is now old code. // All of this is now old code.

View file

@ -8,10 +8,10 @@ import helmet from 'helmet';
import http from 'http'; import http from 'http';
import createRammerhead from 'rammerhead/src/server/index.js'; import createRammerhead from 'rammerhead/src/server/index.js';
import { createBareServer } from '@tomphttp/bare-server-node'; import { createBareServer } from '@tomphttp/bare-server-node';
import wisp from "wisp-server-node"; import wisp from 'wisp-server-node';
import { epoxyPath } from "@mercuryworkshop/epoxy-transport"; import { epoxyPath } from '@mercuryworkshop/epoxy-transport';
import { baremuxPath } from "@mercuryworkshop/bare-mux/node"; import { baremuxPath } from '@mercuryworkshop/bare-mux/node';
import { uvPath } from "@titaniumnetwork-dev/ultraviolet"; import { uvPath } from '@titaniumnetwork-dev/ultraviolet';
const config = JSON.parse(await readFile(new URL('./config.json', import.meta.url))); const config = JSON.parse(await readFile(new URL('./config.json', import.meta.url)));
const { pages, text404 } = pkg; const { pages, text404 } = pkg;
@ -104,9 +104,9 @@ router.get('/', async (req, res) => res.send(paintSource(loadTemplates(tryReadFi
app.use(router); app.use(router);
app.use(express.static(path.join(__dirname, 'views'))); app.use(express.static(path.join(__dirname, 'views')));
app.use("/uv/", express.static(uvPath)); app.use('/uv/', express.static(uvPath));
app.use("/epoxy/", express.static(epoxyPath)); app.use('/epoxy/', express.static(epoxyPath));
app.use("/baremux/", express.static(baremuxPath)); app.use('/baremux/', express.static(baremuxPath));
app.disable('x-powered-by'); app.disable('x-powered-by');

View file

@ -20,19 +20,19 @@ terms = tryReadFile(path.normalize(__dirname + '/views/pages/misc/deobf/tos.html
settings = tryReadFile(path.normalize(__dirname + '/views/pages/misc/deobf/settings.html')), settings = tryReadFile(path.normalize(__dirname + '/views/pages/misc/deobf/settings.html')),
loadTemplates = str => { loadTemplates = str => {
str = insertText("<!--HEADER-->", str, header); str = insertText('<!--HEADER-->', str, header);
str = insertText("<!--FOOTER-->", str, footer); str = insertText('<!--FOOTER-->', str, footer);
// Never used // Never used
// str = insertText("<!--DESC-->", str, description); // str = insertText('<!--DESC-->', str, description);
// Used only on docs.html // Used only on docs.html
str = insertText("<!--DOCS-->", str, documentation); str = insertText('<!--DOCS-->', str, documentation);
// Used only on faq.html // Used only on faq.html
str = insertText("<!--FAQ-->", str, faq); str = insertText('<!--FAQ-->', str, faq);
// Used only on terms.html // Used only on terms.html
str = insertText("<!--TOS-->", str, terms); str = insertText('<!--TOS-->', str, terms);
// Used only on csel.html // Used only on csel.html
str = insertText("<!--SETTINGS-->", str, settings); str = insertText('<!--SETTINGS-->', str, settings);
return str; return str;
}; };

View file

@ -1016,7 +1016,7 @@ details[open] summary {
height: 100%; height: 100%;
background-color: var(--nord1); background-color: var(--nord1);
overflow: hidden; overflow: hidden;
display: block; display: none;
z-index: 1; z-index: 1;
} }

View file

@ -6,22 +6,27 @@
const shimmerEffects = document.querySelectorAll(".box-card"); const shimmerEffects = document.querySelectorAll(".box-card");
// Attach CSS variables, mouse-x and mouse-y, to elements that will be
// given shimmer effects, by adding or modifying the style attribute.
// CSS calculates and renders the actual shimmer effect from there.
shimmerEffects.forEach(shimmerEffect => { shimmerEffects.forEach(shimmerEffect => {
shimmerEffect.addEventListener("mousemove", handleMouseMove); shimmerEffect.addEventListener("mousemove", handleMouseMove);
shimmerEffect.addEventListener("mouseleave", handleMouseLeave); shimmerEffect.addEventListener("mouseleave", handleMouseLeave);
}); });
function handleMouseMove(e) { // Track the cursor position with respect to the top left of the card.
// The "this" keyword gets the element that invoked the event listener.
const handleMouseMove = e => {
const rect = this.getBoundingClientRect(); const rect = this.getBoundingClientRect();
const x = e.clientX - rect.left; const x = e.clientX - rect.left;
const y = e.clientY - rect.top; const y = e.clientY - rect.top;
this.style.setProperty("--mouse-x", `${x}px`); this.style.setProperty("--mouse-x", `${x}px`);
this.style.setProperty("--mouse-y", `${y}px`); this.style.setProperty("--mouse-y", `${y}px`);
} };
function handleMouseLeave() { // Reset the cursor tracking variables when the cursor leaves the card.
const handleMouseLeave = () => {
this.style.setProperty("--mouse-x", `50%`); this.style.setProperty("--mouse-x", `50%`);
this.style.setProperty("--mouse-y", `50%`); this.style.setProperty("--mouse-y", `50%`);
} };

View file

@ -4,66 +4,43 @@
/* MAIN Holy Unblocker LTS Common Script /* MAIN Holy Unblocker LTS Common Script
/* ----------------------------------------------- */ /* ----------------------------------------------- */
function tryGetElement(id) { // Used in scripts outside this file.
return document.getElementById(id) || {}; const tryGetElement = id => document.getElementById(id) || {};
}
/** /**
* Get the preferred apex domain name. * Get the preferred apex domain name.
* Not exactly apex, as any subdomain other than those listed will be ignored. * Not exactly apex, as any subdomain other than those listed will be ignored.
**/ **/
function getDomain() { const getDomain = () => location.host.replace(/^(www|edu|cooking|beta)\./, "");
return location.host.replace(/^(www|edu|cooking|beta)\./, "");
}
/* STEALTH FRAME */ /* STEALTH FRAME */
function goFrame(url) { const goFrame = url => {
localStorage.setItem("huframesrc", url); localStorage.setItem("huframesrc", url);
window.location.href = "?s"; location.href = "?s";
} };
function goToUrl(url, stealth, nolag) { const goToUrl = (url, stealth, nolag) => {
if (stealth) { stealth ? goFrame(url, nolag) : location.href = url;
goFrame(url, nolag); };
} else {
window.location.href = url;
}
}
/* COOKIE AUTH DEMO */ /* COOKIE AUTH DEMO */
function setAuthCookie(s, lax) { const setAuthCookie = (s, lax) => {
document.cookie = document.cookie = s + `; expires=${Date.now() + 259200}; SameSite=${lax ? "Lax" : "None"}; domain=.${getDomain()}; path=/; Secure;`;
s + };
"; expires=" +
(Date.now() + 259200) +
"; SameSite=" +
(lax ? "Lax" : "None") +
"; domain=." +
getDomain() +
"; path=/; Secure;";
}
/* OMNIBOX */ /* OMNIBOX */
const sx = "bing.com" + "/search?q="; const sx = "bing.com" + "/search?q=";
function omnibox(url) { const omnibox = url =>
if (url.substring(0, 4) == "http") { (url.indexOf("http")
return url; ? "https://" + (url.indexOf(".") < 1 ? sx : "")
} else if (url.includes("." || "")) { : "")
return "https://" + url; + url;
} else {
return "https://" + sx + url;
}
}
function uvUrl(url) { const uvUrl = url => location.origin + __uv$config.prefix + __uv$config.encodeUrl(omnibox(url));
return (
location.origin + __uv$config.prefix + __uv$config.encodeUrl(omnibox(url))
);
}
/* RAMMERHEAD CONFIGURATION */ /* RAMMERHEAD CONFIGURATION */

View file

@ -1,9 +1,137 @@
/* ----------------------------------------------- /* -----------------------------------------------
/* Authors: OlyB /* Authors: OlyB and Yoct
/* GNU Affero General Public License v3.0: https://www.gnu.org/licenses/agpl-3.0.en.html /* GNU Affero General Public License v3.0: https://www.gnu.org/licenses/agpl-3.0.en.html
/* Adapted and modified by Yoct.
/* Settings Menu /* Settings Menu
/* ----------------------------------------------- */ /* ----------------------------------------------- */
// Determine the expiration date of a new cookie.
let date = new Date();
date.setFullYear(date.getFullYear() + 100);
date = date.toUTCString();
// All cookies should be secure and are intended to work in iframes.
const setCookie = (name, value) => {
document.cookie = name + `=${encodeURIComponent(value)}; expires=${date}; SameSite=None; Secure;`;
},
removeCookie = name => {
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT; ";
},
readCookie = async name => {
for (let cookie of document.cookie.split("; "))
// Get the first cookie that has the same name.
if (!cookie.indexOf(name + "="))
// Return the cookie's stored content.
return decodeURIComponent(cookie.slice(name.length + 1));
},
// Customize the page's title.
pageTitle = value => {
let tag = document.getElementsByTagName("title")[0] || document.createElement("title");
tag.innerHTML = value;
document.head.appendChild(tag);
},
// Set the page's favicon to a new URL.
pageIcon = value => {
let tag = document.querySelector("link[rel*='icon']") || document.createElement("link");
tag.rel = "icon";
tag.href = value;
document.head.appendChild(tag);
},
// Make a small stylesheet to override a setting from the main stylesheet.
pageShowAds = () => {
let advertising = document.createElement("style");
advertising.id = "advertising";
advertising.innerText = ".ad { display:block; }";
(document.head || document.body || document.documentElement || document).appendChild(advertising);
},
// Remove the stylesheet made by the function above, if it exists.
pageHideAds = () => {
(document.getElementById("advertising")||new Text()).remove();
};
// Load a custom page title and favicon if it was previously stored.
readCookie("HBTitle").then(s => (s != undefined) && pageTitle(s));
readCookie("HBIcon").then(s => (s != undefined) && pageIcon(s));
// Ads are disabled by default. Load ads if ads were enabled previously.
readCookie("HBHideAds").then(s => (s != "false") ? pageHideAds() : pageShowAds((document.getElementById("hideads") || {}).checked = 0));
// All code below is used by the Settings UI in the navigation bar.
if (document.getElementById("csel")) {
// Allow users to set a custom title with the UI.
document.getElementById("titleform").addEventListener("submit", e => {
e.preventDefault();
e = this.firstElementChild;
if (e.value) {
pageTitle(e.value);
setCookie("HBTitle", e.value);
e.value = "";
} else {
alert("Please provide a title.");
}
}, false);
// Allow users to set a custom favicon with the UI.
document.getElementById("iconform").addEventListener("submit", e => {
e.preventDefault();
e = this.firstElementChild;
if (e.value) {
pageIcon(e.value);
setCookie("HBIcon", e.value);
e.value = "";
} else {
alert("Please provide an icon URL.");
}
}, false);
// Allow users to reset the title and favicon to default with the UI.
document.getElementById("cselreset").addEventListener("click", () => {
if (confirm("Reset the title and icon to default?")) {
removeCookie("HBTitle");
removeCookie("HBIcon");
pageTitle("Holy Unblocker");
pageIcon("assets/img/icon.png");
}
}, false);
// Allow users to make a new about:blank tab and view the site from there.
// An iframe of the current page is inserted into the new tab.
document.getElementById("cselab").addEventListener("click", () => {
let win = window.open();
let iframe = win.document.createElement("iframe");
iframe.style = "width: 100%; height: 100%; border: none; overflow: hidden; margin: 0; padding: 0; position: fixed; top: 0; left: 0";
iframe.src = location.href;
win.document.body.appendChild(iframe);
});
// Allow users to enable or disable ads with the UI.
document.getElementById("hideads").addEventListener("change", e => {
if (e.target.checked) {
pageHideAds();
setCookie("HBHideAds", "true");
} else {
pageShowAds();
setCookie("HBHideAds", "false");
}
}, false);
}
/* -----------------------------------------------
/* Original code written by OlyB
/* -----------------------------------------------
(function() { (function() {
let date = new Date(); let date = new Date();
date.setFullYear(date.getFullYear() + 100); date.setFullYear(date.getFullYear() + 100);
@ -134,3 +262,4 @@ decodeURIComponent(atob("JTNDcCUyMGNsYXNzJTNEJTIyY3NlbHRpdGxlJTIyJTNFVGFiJTIwQ2x
}, false); }, false);
} }
})(); })();
*/

View file

@ -1,16 +1,16 @@
<p class="cseltitle">Tab Cloak</p> <p class=cseltitle>Tab Cloak</p>
<p class="csellabel">Change the title:</p> <p class=csellabel>Change the title:</p>
<form class="cselform" id="titleform"> <form class=cselform id=titleform>
<input type="text" placeholder="Tab Title" spellcheck="false"><input class="cselbutton" type="submit" value="Apply"> <input type=text placeholder=Tab Title spellcheck=false><input class=cselbutton type=submit value=Apply>
</form> </form>
<p class="csellabel">Change the <a href="/?i">icon</a>:</p> <p class=csellabel>Change the <a href=/?i>icon</a>:</p>
<form class="cselform" id="iconform"> <form class=cselform id=iconform>
<input type="text" placeholder="Icon URL" spellcheck="false"><input class="cselbutton" type="submit" value="Apply"> <input type=text placeholder=Icon URL spellcheck=false><input class=cselbutton type=submit value=Apply>
</form> </form>
<input id="cselreset" class="cselbutton" type="button" value="Reset"> <input id=cselreset class=cselbutton type=button value=Reset>
<input id="cselab" class="cselbutton" type="button" value="about:blank"> <input id=cselab class=cselbutton type=button value=about:blank>
<p class="csellabel"> <p class=csellabel>
<input id="hideads" type="checkbox"> <input id=hideads type=checkbox checked>
<span>Hide Ads</span> <span>Hide Ads</span>
</p> </p>
<p>Ads are disabled forever.</p> <p>Ads are disabled forever.</p>