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.
#### 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)
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.
// Will edit str by replacing all matches of lis with newText.
// Usage: insertText(["<Example1>", "<Example2>"],
// "<Example1> Big Giant Paragraph <Example2> Smol Paragraph",
// Usage: insertText(['<Example1>', '<Example2>'],
// '<Example1> Big Giant Paragraph <Example2> Smol Paragraph',
// stringOrFunctionToGenerateNewText);
*/
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;
// 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.
while ((position = str.indexOf(placeholder)) >= 0)
str = str.slice(0, position)
+ (typeof newText == "function" ? newText() : newText)
+ (typeof newText == 'function' ? newText() : newText)
+ str.slice(position + placeholder.length);
}
return str;
@ -34,7 +33,7 @@ const insertText = (lis, str, newText) => {
// changes with each time it is loaded.
const randomListItem = lis => () => lis[Math.random() * lis.length | 0],
charset = ["&#173;", "&#8203;", "&shy;", "<wbr>"],
charset = ['&#173;', '&#8203;', '&shy;', '<wbr>'],
getRandomChar = randomListItem(charRandom),
insertCharset = str => insertText(
charset,
@ -44,14 +43,14 @@ insertCharset = str => insertText(
getRandomSplash = randomListItem(splashRandom),
hutaoInsert = str => insertText(
"<!--HUTAOWOA-->",
'<!--HUTAOWOA-->',
str,
getRandomSplash
),
getCookingText = () => `<span style="display:none" data-fact="${randomListItem(vegetables)()}">${randomListItem(cookingInserts)()}</span>`,
insertCooking = str => insertText(
"<!-- IMPORTANT-HUTAOCOOKINGINSERT-DONOTDELETE -->",
'<!-- IMPORTANT-HUTAOCOOKINGINSERT-DONOTDELETE -->',
str,
getCookingText
),
@ -67,7 +66,7 @@ cacheBusting = str => {
paintSource = str => insertCharset(hutaoInsert(insertCooking(cacheBusting(str)))),
// 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.

View file

@ -8,10 +8,10 @@ import helmet from 'helmet';
import http from 'http';
import createRammerhead from 'rammerhead/src/server/index.js';
import { createBareServer } from '@tomphttp/bare-server-node';
import wisp from "wisp-server-node";
import { epoxyPath } from "@mercuryworkshop/epoxy-transport";
import { baremuxPath } from "@mercuryworkshop/bare-mux/node";
import { uvPath } from "@titaniumnetwork-dev/ultraviolet";
import wisp from 'wisp-server-node';
import { epoxyPath } from '@mercuryworkshop/epoxy-transport';
import { baremuxPath } from '@mercuryworkshop/bare-mux/node';
import { uvPath } from '@titaniumnetwork-dev/ultraviolet';
const config = JSON.parse(await readFile(new URL('./config.json', import.meta.url)));
const { pages, text404 } = pkg;
@ -104,9 +104,9 @@ router.get('/', async (req, res) => res.send(paintSource(loadTemplates(tryReadFi
app.use(router);
app.use(express.static(path.join(__dirname, 'views')));
app.use("/uv/", express.static(uvPath));
app.use("/epoxy/", express.static(epoxyPath));
app.use("/baremux/", express.static(baremuxPath));
app.use('/uv/', express.static(uvPath));
app.use('/epoxy/', express.static(epoxyPath));
app.use('/baremux/', express.static(baremuxPath));
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')),
loadTemplates = str => {
str = insertText("<!--HEADER-->", str, header);
str = insertText("<!--FOOTER-->", str, footer);
str = insertText('<!--HEADER-->', str, header);
str = insertText('<!--FOOTER-->', str, footer);
// Never used
// str = insertText("<!--DESC-->", str, description);
// str = insertText('<!--DESC-->', str, description);
// Used only on docs.html
str = insertText("<!--DOCS-->", str, documentation);
str = insertText('<!--DOCS-->', str, documentation);
// Used only on faq.html
str = insertText("<!--FAQ-->", str, faq);
str = insertText('<!--FAQ-->', str, faq);
// Used only on terms.html
str = insertText("<!--TOS-->", str, terms);
str = insertText('<!--TOS-->', str, terms);
// Used only on csel.html
str = insertText("<!--SETTINGS-->", str, settings);
str = insertText('<!--SETTINGS-->', str, settings);
return str;
};

View file

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

View file

@ -6,22 +6,27 @@
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 => {
shimmerEffect.addEventListener("mousemove", handleMouseMove);
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 x = e.clientX - rect.left;
const y = e.clientY - rect.top;
this.style.setProperty("--mouse-x", `${x}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-y", `50%`);
}
};

View file

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

View file

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