// Welcome to the main Nebula script // This script handles all the tasks neccesary for a proxy. // What this doesn't include is the actual proxies, just the neccesary tasks in order for the proxies to be able to preform, such as registering the service worker required by Interception proxies. // Documentation Writers/Contributors: // GreenWorld#0001 (Discord) / GreenyDev (Github) // If you would like to contribute, feel free to open a pull request. // These docs are not finished // Navigation controls for smaller devices // Executed in the inline HTML function openNav() { document.getElementById("sidenav").style.width = "260px" } function closeNav() { document.getElementById("sidenav").style.width = "0px" } window.addEventListener("load", () => { // Register the service workers for Osana and Ultraviolet proxy protocols // This is a better method than registering onsubmit because this allows the ability to use proxied links on the main page. navigator.serviceWorker.register("./sw.js", { scope: "/service/", }) // Get's the current day using the Date function built in. // A dependency for displaying time - displayTime(void) function getDayName(dateStr, locale) { var date = new Date(dateStr) return date.toLocaleDateString(locale, { weekday: "long" }) } // The main function to show the time on the main page // needs to be initialized by a call (only one) // Dependent on getDayName function function displayTime() { var date = new Date() var h = date.getHours() // 0 - 23 var m = date.getMinutes() // 0 - 59 var s = date.getSeconds() // 0 - 59 var session = "AM" if (h == 0) { h = 12 } if (h > 12) { h = h - 12 session = "PM" } h = h < 10 ? "0" + h : h m = m < 10 ? "0" + m : m s = s < 10 ? "0" + s : s // Repeat itself every second setTimeout(displayTime, 1000) // Get today's date var today = new Date() var dd = String(today.getDate()).padStart(2, "0") var mm = String(today.getMonth() + 1).padStart(2, "0") //January is 0! var yyyy = today.getFullYear() today = mm + "/" + dd + "/" + yyyy var time = h + ":" + m document.getElementById("digitalClock").innerHTML = getDayName(today, "us-US") + ", " + time + " " + session + "." return time } // initialize the time function displayTime() // Link evaluation // This functions' purpose is to check a string of text (the argument) // it recognizes whether a string is a URL or not, and it returns a true or false value function isUrl(val = "") { if ( /^http(s?):\/\//.test(val) || (val.includes(".") && val.substr(0, 1) !== " ") ) return true return false } const useNoGG = false const proxy = localStorage.getItem("proxy") || "uv" const inpbox = document.querySelector("form") // Display the "loading" indicators on the main page, looks much better than a static/still screen. inpbox.addEventListener("submit", (event) => { // Prevents the default event tasks event.preventDefault() console.log("Connecting to service -> loading") const loader = document.getElementById("lpoader") const texts = document.getElementById("connecterText") // Adjust size as neccesary const loadConstructer = loader.style const textConstructer = texts.style loadConstructer.display = "flex" loadConstructer.justifyContent = "center" // Changing the text over multiple periods of time creates character, and aliveness (is that even a word?) setTimeout(() => { document.getElementById("connecterText").style.fontSize = "12px" document.getElementById("connecterText").innerHTML = "Due to high server load, this may take a while." }, 3200) setTimeout(() => { document.getElementById("connecterText").style.fontSize = "14px" document.getElementById("connecterText").innerHTML = "Hmmm.. Something isn't right.." }, 17000) }) // Form submission const form = document.querySelector("form") form.addEventListener("submit", (event) => { event.preventDefault() // Check if the service worker (commonly called SW) is registered if (typeof navigator.serviceWorker === "undefined") alert( "An error occured registering your service worker. Please contact support - discord.gg/unblocker" ) // if (proxy === "uv" || proxy === "osana") { // Re-register the service worker incase it failed to onload navigator.serviceWorker .register("./sw.js", { scope: "/service/", }) .then(() => { const value = event.target.firstElementChild.value let url = value.trim() if (!isUrl(url)) url = "https://www.google.com/search?q=" + url if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url // encode the URL for UltraViolet let redirectTo = proxy === "uv" ? __uv$config.prefix + __uv$config.encodeUrl(url) : __osana$config.prefix + __osana$config.codec.encode(url) const option = localStorage.getItem("nogg") if (option === "on") { stealthEngine(redirectTo) } else { setTimeout(() => { // If StealthMode is off, this is the enabled option. const _popout = window.open("/blob", "_self") const blob = _popout.document // Write all of the neccesary page elements, and the Options including the cloak (if enabled) // The blob writing is just the background elements, like the "Nebula is loading your content, please wait" screen. It does not carry proxied content, or even the iframe. blob.write(`
Nebula is loading your content!
Please wait
`) // inside of the blob, create and append the Iframe element which WILL carry the proxied content. const iframe = blob.createElement("iframe") const style = iframe.style const img = blob.createElement("link") const link = location.href // We attach ARC because it supports us, keeping our arc link there would be greatly appreciated :) const arcSrc = blob.createElement("script") arcSrc.setAttribute( "src", "https://arc.io/widget.min.js#BgaWcYfi" ) // Arc requires the Async attribute // Async means not running parallel to other tasks, so it loads seperately to everything else (in a sense) // Aysnchronous and Synchronous are somewhat difficult topics, so we recommend you arcSrc.setAttribute("async", "") blob.head.appendChild(arcSrc) img.rel = "icon" img.href = "https://static.nebulacdn.xyz/content/images/nebula_logo_619x619.png" blob.title = "Nebula" // slice the link like some nice fruit :) // Removing the '/' from 'whateverthislinkis.gay/' // ^ var currentLink = link.slice(0, link.length - 1) // To attribute the iframe to a source, we need to + the current link (post-slice) to the requested website, which is passed through the functions argument iframe.src = currentLink + redirectTo // Style the Iframe to fill the entire screen and remove the bessels. style.position = "fixed" style.top = style.bottom = style.left = style.right = 0 style.border = style.outline = "none" style.width = style.height = "100%" // finally, append the iframe to the blob's (window) body blob.body.appendChild(iframe) }, 1000) } }) } }) // Stealth engine, a dependency for everything above. function stealthEngine(encodedURL) { // Remember that the EncodedURL argument must be pre-encoded, or encoded before the function is called. // This function does not encode the argument at all! // Initialize the variable let inFrame // make sure there isn't a window open already try { inFrame = window !== top } catch (e) { inFrame = true } setTimeout(() => { // Basically, a checklist to make sure that an error won't occur. // In this if statement, we're checking if an iframe is already being opened, if popups are disabled, and if the user agent IS NOT firefox (firefox sucks, sorry Moz) if (!inFrame && !navigator.userAgent.includes("Firefox")) { const popup = open("about:blank", "_blank") if (!popup || popup.closed) { alert( "StealthEngine was unable to open a popup. (do you have popups disabled?)" ) } else { const doc = popup.document const iframe = doc.createElement("iframe") const style = iframe.style // Favicon attachment const img = doc.createElement("link") const arcSrc = doc.createElement("script") // We attach ARC because it supports us, keeping our arc link there would be greatly appreciated :) arcSrc.setAttribute("src", "https://arc.io/widget.min.js#BgaWcYfi") arcSrc.setAttribute("async", "") doc.head.appendChild(arcSrc) const link = location.href img.rel = "icon" img.href = "https://ssl.gstatic.com/images/branding/product/1x/drive_2020q4_32dp.png" doc.title = getRandomName() var currentLink = link.slice(0, link.length - 1) iframe.src = currentLink + encodedURL style.position = "fixed" style.top = style.bottom = style.left = style.right = 0 style.border = style.outline = "none" style.width = style.height = "100%" doc.body.appendChild(iframe) } } }, 1500) } }) // Set the option var option = localStorage.getItem("nogg") function toggleNoGG() { if (option === "on") { option = "off" localStorage.setItem("nogg", "off") } else { option = "on" localStorage.setItem("nogg", "on") } } var option2 = localStorage.getItem("ADVcloak") function toggleClickoff() { if (option2 === "on") { option2 = "off" localStorage.setItem("ADVcloak", "off") } else { option2 = "on" localStorage.setItem("ADVcloak", "on") } } const storedSetTheme = localStorage.getItem("theme") function switchProxy() { var selecter = document.getElementById("proxySwitcher") var selectedOption = selecter.value localStorage.setItem("proxy", selectedOption) var storedChoice = localStorage.getItem("proxy") console.log(selectedOption) } if (storedSetTheme == null) { localStorage.setItem("theme", "dark") } function switchTheme() { var selecter = document.getElementById("themeSwitcher") var selectedOption = selecter.value if (selectedOption == "dark") { changeCSS("--background-primary", "#191724", true) changeCSS("--navbar-color", "#26233a", true) changeCSS("--navbar-height", "60px", true) changeCSS("--navbar-text-color", "#7967dd", true) changeCSS("--input-text-color", "#e0def4", true) changeCSS("--input-placeholder-color", "#6e6a86", true) changeCSS("--input-background-color", "#1f1d2e", true) changeCSS("--input-placeholder-color", "white", true) changeCSS("--input-border-color", "#eb6f92", true) changeCSS("--input-border-size", "1.3px", true) changeCSS("--navbar-link-color", "#e0def4", true) changeCSS("--navbar-font", '"Roboto"', true) changeCSS("--navbar-logo-filter", "invert(0%)", true) changeCSS("--text-color-primary", "#e0def4", true) localStorage.setItem("theme", "dark") } if (selectedOption == "light") { changeCSS("--background-primary", "#d8d8d8", true) changeCSS("--navbar-color", "#a2a2a2", true) changeCSS("--navbar-height", "4em", true) changeCSS("--navbar-text-color", "#000000", true) changeCSS("--input-text-color", "#e0def4", true) changeCSS("--input-placeholder-color", "white", true) changeCSS("--input-background-color", "black", true) changeCSS("--input-border-color", "#eb6f92", true) changeCSS("--input-border-size", "1.3px", true) changeCSS("--navbar-link-color", "#000000", true) changeCSS("--navbar-font", '"Roboto"', true) changeCSS("--navbar-logo-filter", "invert(30%)", true) changeCSS("--text-color-primary", "#303030", true) localStorage.setItem("theme", "light") } if (selectedOption == "custom") { let response = prompt("Please enter the code for a custom theme:", "") alert("This feature is not ready yet. Please try again later.") } } function defaultThemes() {} function changeCSS(variable, value, saveBool) { document.documentElement.style.setProperty(variable, value) if (saveBool === true) { saveCSS(variable, value) } } function saveCSS(variable, value) { localStorage.setItem(variable, value) } window.onload = function () { function setCookie(cname, cvalue, exdays) { const d = new Date() d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000) let expires = "expires=" + d.toUTCString() document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/" } function getCookie(cname) { let name = cname + "=" let decodedCookie = decodeURIComponent(document.cookie) let ca = decodedCookie.split(";") for (let i = 0; i < ca.length; i++) { let c = ca[i] while (c.charAt(0) == " ") { c = c.substring(1) } if (c.indexOf(name) == 0) { return c.substring(name.length, c.length) } } return "" } function httpGet(theUrl) { var xmlHttp = new XMLHttpRequest() xmlHttp.open("GET", theUrl, false) // false for synchronous request xmlHttp.send(null) return xmlHttp.responseText } if (httpGet("/verification") == "true") { if (getCookie("verifiedAccess") == "") { console.log("COOKIE NOT FOUND - ENTRY NOT PERMITTED") window.location = "/unv.html" } else { console.log("COOKIE RECOGNIZED - ENTRY PERMITTED ") } } let background = localStorage.getItem("--background-primary") let navbar = localStorage.getItem("--navbar-color") let navbarHeight = localStorage.getItem("--navbar-height") let navbarText = localStorage.getItem("--navbar-text-color") let inputText = localStorage.getItem("--input-text-color") let inputPlaceholder = localStorage.getItem("--input-placeholder-color") let inputBackground = localStorage.getItem("--input-background-color") let inputBorder = localStorage.getItem("--input-border-color") let inputBorderSize = localStorage.getItem("--input-border-size") let navbarFont = localStorage.getItem("--navbar-font") let navbarLink = localStorage.getItem("--navbar-link-color") let navbarLogoFilter = localStorage.getItem("--navbar-logo-filter") let textColorPrimary = localStorage.getItem("--text-color-primary") changeCSS("--background-primary", background) changeCSS("--navbar-color", navbar) changeCSS("--navbar-height", navbarHeight) changeCSS("--navbar-text-color", navbarText) changeCSS("--input-text-color", inputText) changeCSS("--input-placeholder-color", inputPlaceholder) changeCSS("--input-background-color", inputBackground) changeCSS("--input-border-color", inputBorder) changeCSS("--input-border-size", inputBorderSize) changeCSS("--navbar-link-color", navbarLink) changeCSS("--navbar-font", navbarFont) changeCSS("--navbar-logo-filter", navbarLogoFilter) changeCSS("--text-color-primary", textColorPrimary) } // Resets themes function resetViews() { changeCSS("--background-primary", "#191724", true) changeCSS("--navbar-color", "#26233a", true) changeCSS("--navbar-height", "60px", true) changeCSS("--navbar-text-color", "rgb(121 103 221)", true) changeCSS("--navbar-link-color", "#e0def4", true) changeCSS("--navbar-font", '"Roboto"', true) changeCSS("--input-text-color", "#e0def4", true) changeCSS("--input-placeholder-color", "#6e6a86", true) changeCSS("--input-background-color", "#1f1d2e", true) changeCSS("--input-placeholder-color", "white", true) changeCSS("--input-border-color", "#eb6f92", true) changeCSS("--input-border-size", "1.3px", true) return "All views reset" } // Extra logging for support function log() { setTimeout( console.log.bind( console, "%cWelcome To Nebula", "background: #3F51B5;color:#FFF;padding:5px;border-radius: 5px;line-height: 26px; font-size:30px;" ) ) setTimeout( console.log.bind( console, "%c If you are seeing this, Nebula's main script has succesfully loaded!", "background: green;color:#FFF;padding:5px;border-radius: 5px;line-height: 26px; font-size:12px;" ) ) setTimeout( console.log.bind( console, "%cIf you encounter an error, contact our support team on discord. Copy and paste the information below and send it in the ticket", "background: red;color:#FFF;padding:5px;border-radius: 5px;line-height: 26px; font-size:12px;" ) ) let enabledCookies = navigator.cookieEnabled let appName = navigator.appName // @deprecated let product = navigator.product // @deprecated let agent = navigator.userAgent let version = navigator.appVersion // @deprecated let platform = navigator.platform // @deprecated let online = navigator.onLine let userAgent = navigator.userAgent let browserName let diagnosticDomain = window.location.href if (userAgent.match(/chrome|chromium|crios/i)) { browserName = "chrome" } else if (userAgent.match(/firefox|fxios/i)) { browserName = "firefox" } else if (userAgent.match(/safari/i)) { browserName = "safari" } else if (userAgent.match(/opr\//i)) { browserName = "opera" } else if (userAgent.match(/edg/i)) { browserName = "edge" } else { browserName = "No browser detection" } setTimeout( console.log.bind( console, `%cInformation: \n URL: ${diagnosticDomain} \n BrowserName: ${browserName} \n IsOnline: ${online} \n agent: ${userAgent}, `, "background: gray;color:#FFF;padding:3px;border-radius: 0px;line-height: 26px; font-size:6px;" ) ) } log() // Notification Banners // "Saved" notification function saveIc() { console.log("Checked") var notification = `
Success! Your settings have been saved!
` document.getElementById("notifhere").innerHTML = notification setTimeout(() => { var NotificationOBJ = document.getElementById("notifhere") }, 2000) } // The "You have unsaved changes" banner. You can remove this but it isn't recommended function unsavedChanges() { var notification = `
Danger! You have unsaved changes!
` document.getElementById("notifhere").innerHTML = notification setTimeout(() => { var NotificationOBJ = document.getElementById("notifhere") }, 2000) } // Adjectives and surnames for a more advanced stealth engine. // Used together to generate random names for the tab name const adjectives = [ "admiring", "adoring", "affectionate", "agitated", "amazing", "angry", "awesome", "beautiful", "blissful", "bold", "boring", "brave", "busy", "charming", "clever", "cool", "compassionate", "competent", "condescending", "confident", "cranky", "crazy", "dazzling", "determined", "distracted", "dreamy", "eager", "ecstatic", "elastic", "elated", "elegant", "eloquent", "epic", "exciting", "fervent", "festive", "flamboyant", "focused", "friendly", "frosty", "funny", "gallant", "gifted", "goofy", "gracious", "great", "happy", "hardcore", "heuristic", "hopeful", "hungry", "infallible", "inspiring", "interesting", "intelligent", "jolly", "jovial", "keen", "kind", "laughing", "loving", "lucid", "magical", "mystifying", "modest", "musing", "naughty", "nervous", "nice", "nifty", "nostalgic", "objective", "optimistic", "peaceful", "pedantic", "pensive", "practical", "priceless", "quirky", "quizzical", "recursing", "relaxed", "reverent", "romantic", "sad", "serene", "sharp", "silly", "sleepy", "stoic", "strange", "stupefied", "suspicious", "sweet", "tender", "thirsty", "trusting", "unruffled", "upbeat", "vibrant", "vigilant", "vigorous", "wizardly", "wonderful", "xenodochial", "youthful", "zealous", "zen", ], surnames = [ "albattani", "allen", "almeida", "antonelli", "agnesi", "archimedes", "ardinghelli", "aryabhata", "austin", "babbage", "banach", "banzai", "bardeen", "bartik", "bassi", "beaver", "bell", "benz", "bhabha", "bhaskara", "black", "blackburn", "blackwell", "bohr", "booth", "borg", "bose", "bouman", "boyd", "brahmagupta", "brattain", "brown", "buck", "burnell", "cannon", "carson", "cartwright", "carver", "cerf", "chandrasekhar", ] // Random number generator // Dependency of getRandomName function function getRandomNumber(min, max) { return Math.floor(Math.random() * (max - min) + min) } // Random name generator function getRandomName() { const random1 = getRandomNumber(0, adjectives.length) const random2 = getRandomNumber(0, surnames.length) const adjective = adjectives[random1] const surname = surnames[random2] // Connect the adjective and surname together to create a random name const randomName = adjective + "-" + surname // Return it so it can be called later as a variable for the Tab Name. return randomName } // Check if the Browser variable is undefined // This is unused as of now but it could be used for better cloaking in the future, specifically with activeTab if (typeof browser === "undefined") { // Initialize the browser variable var browser = chrome } browser = chrome // Clickoff cloaking // This function is called as a callback during the event listener function handleTabLeave() { var link = document.querySelector("link[rel~='icon']") if (localStorage.getItem("ADVcloak") == "on") { if (document.title == "Nebula") { if (!link) { link = document.createElement("link") link.rel = "icon" document.getElementsByTagName("head")[0].appendChild(link) } link.href = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQo7AE3IF34XPGyseQjkXIOsWXpkZiLlMjSAwySjcJSPAwlv3hnGKi1&usqp=CAU" document.title = "Google" } else if (document.title == "Google") { document.title = "Nebula" if (!link) { link = document.createElement("link") link.rel = "icon" document.getElementsByTagName("head")[0].appendChild(link) } link.href = "https://camo.githubusercontent.com/b565ae2e136e0ac6023e7099288a62382de7c2b8cdce86a8b90449b86649434c/68747470733a2f2f6e6562756c6170726f78792e6e6562756c612e62696f2f696d616765732f6c6f676f2e706e67" } else { return false } } } // Create and Add the event listener document.addEventListener("visibilitychange", handleTabLeave) const stealthStored = localStorage.getItem('nogg') function link(_link) { if (stealthStored == "on") { let inFrame try { inFrame = window !== top } catch (e) { inFrame = true } setTimeout(() => { if (!inFrame && !navigator.userAgent.includes("Firefox")) { const popup = open("about:blank", "_blank") if (!popup || popup.closed) { alert("Popups are disabled!") } else { const doc = popup.document const iframe = doc.createElement("iframe") const style = iframe.style const img = doc.createElement("link") const link = location.href img.rel = "icon" img.href = "https://ssl.gstatic.com/images/branding/product/1x/drive_2020q4_32dp.png" doc.title = getRandomName() var currentLink = link.slice(0, link.length - 1) iframe.src = currentLink + "/service/go/" + __uv$config.encodeUrl(_link) style.position = "fixed" style.top = style.bottom = style.left = style.right = 0 style.border = style.outline = "none" style.width = style.height = "100%" doc.body.appendChild(iframe) } } }, 0200) } else { location.href = "service/go/" + __uv$config.encodeUrl("https://radon.games/") } }