<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Caub + DNS</title> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet" /> <style> :root { --nc-tx-1: #ffffff; --nc-tx-2: #eeeeee; --nc-bg-1: #090909; --nc-bg-2: #121212; --nc-bg-3: #222222; --nc-lk-1: #7622eb; --nc-lk-2: #5d00e0; } * { background-color: black; color: rgb(255, 255, 255); } body { background-color: black; font-family: Inter, sans-serif; font-size: 15px; margin: 35px; margin-top: 5px; } a { color: cyan; } button { display: inline-block; text-align: center; background: var(--nc-bg-2); color: var(--nc-lk-tx); padding: 3px 6px; border: 1.5px solid var(--nc-bg-3); border-radius: 4px; box-sizing: border-box; cursor: pointer; color: var(--nc-lk-tx); margin: .5rem; } textarea, select, input { padding: 6px 12px; margin-bottom: .5rem; margin-left: .5rem; margin-right: .5rem; background: var(--nc-bg-1); color: var(--nc-tx-2); border: 1px solid var(--nc-bg-3); border-radius: 4px; box-shadow: none; box-sizing: border-box; } .list { line-height: 1.8; } .border { border: 2px solid white; padding: 5px; } .wrapper { margin: 0 auto; } .block1 { float: left; } .block2 { float: right; } code { background-color: #090909; border-radius: 5px; color: rgb(168, 92, 255); } #logBox { font-size: 12px; color: white; background-color: black; padding: 5px; border: 2px solid #0a0a0a; border-radius: 5px; margin-top: 5px; max-height: 180px; top: -30px !important; max-width: 570px; overflow-y: auto; overflow-x: auto; position: relative; } #logBox::-webkit-scrollbar { display: none; } .timestamp { color: #888; font-weight: bold; user-select: none; } .timestamp-colon { user-select: none; } .error { color: #ff3d51; } .info { color: #a8aaff; } .no-select { user-select: none; } </style> </head> <body> <div class="wrapper"> <div class="block1"> <h1>Caub + DNS + Proxy editor</h1> <input id="meteredToggle" type="checkbox" checked>enable metered (update blocker)</input> <br> <input id="dnsEnabled" type="checkbox">edit dns</input> <br> <input type="text" id="dns1" placeholder="Enter IP..." /> <br> <input type="text" id="dns2" placeholder="Enter IP..." /> <br> <input type="text" id="dns3" placeholder="Enter IP..." /> <br> <input type="text" id="dns4" placeholder="Enter IP..." /> <br> <input id="omadaDns" type="checkbox"> OmadaDNS</input> <br> <input id="proxyEnabled" type="checkbox">edit proxy</input> <br> <br> ftp proxy <input type="text" id="ftpProxy" placeholder="socks4://localhost" /> <input value="1080" type="number" id="ftpProxyPort"></input> <br> HTTP proxy <input type="text" id="httpProxy" placeholder="socks4://localhost" /> <input value="1080" type="number" id="httpProxyPort"></input> <br> secure HTTPS proxy <input type="text" id="secureHttpProxy" placeholder="socks4://localhost" /> <input value="1080" type="number" id="secureHttpProxyPort"></input> <br> socks host <input type="text" id="socks" placeholder="localhost" /> <input value="1080" type="number" id="socksProxyPort"></input> <br> domains to exclude as json array <input type="text" value="[]" id="excludeDomains" /> <br> example: <code style="margin-bottom: 60px;">["*.com", "google.com"]</code> </div> <div class="block2"> <h1>Instructions</h1> <div class="list"> <ol> <li>Edit the settings above</li> <li>Go to <code>chrome://network#state</code></li> <li>Scroll to <code>"Favourite Networks"</code></li> <li>Find the wifi network that you are currently connected to</li> <li>Click the <code>+</code> next to the wifi name</li> <li>Copy all the data that appears (the <code>{}</code> curly braces)</li> <li>Paste the data into the box below and press the generate button</li> <li>Click the <code>+</code> under the box to add multiple networks</li> <li>Once you have downloaded the file, go to <code>chrome://network#general</code></li> <li>Scroll to the bottom and click <code>Import ONC</code></li> <li>Open the generated then downloaded file, it should say <code>Networks imported: 1</code></li> <li>Your new "caubbed" network should be configured now!!</li> </ol> </div> <br> <input class="inputData" placeholder="read instructions" /> <div id="extraInputs"></div> <button onclick="addInput()">+</button> <button onclick="removeInput()">-</button> <br> <button onclick="generateONC()" style="color:rgb(168, 92, 255)">Generate ONC file</button> <button onclick="downloadONC()" style="margin-bottom: 60px; color: rgb(68, 255, 124);">Download ONC file</button> <button onclick="copyLog()" style="color:#a8aaff">Copy Log</button> <br> <div id="logBox" class="border"> <strong>Log:</strong> <pre id="logContent"></pre> </div> <br> </div> </div> </div> <script> let oncData = null; function logMessage(message, type = 'info') { const logContent = document.querySelector("#logContent"); const time = new Date(); const timeString = time.toISOString().slice(11, 23).replace('T', ' '); const className = type === 'error' ? 'error' : 'info'; logContent.innerHTML += `<span class="timestamp">${timeString}<span class="timestamp-colon">:</span></span> <span class="${className}">${message}</span>\n`; logContent.scrollTop = logContent.scrollHeight; } function addInput() { logMessage("Added new input field."); document.querySelector("#extraInputs").innerHTML += `<input type="text" class="inputData" />`; } function removeInput() { if (document.querySelector("#extraInputs").lastChild) { logMessage("Removed last input field."); document.querySelector("#extraInputs").lastChild.remove(); } } const omadaDnsValues = ["167.86.91.171", "66.94.105.229", "213.109.163.210", "92.60.37.102"]; const dnsInputs = [ document.getElementById('dns1'), document.getElementById('dns2'), document.getElementById('dns3'), document.getElementById('dns4') ]; const omadaDnsCheckbox = document.getElementById('omadaDns'); omadaDnsCheckbox.addEventListener('change', () => { if (omadaDnsCheckbox.checked) { dnsInputs.forEach((input, index) => { input.value = omadaDnsValues[index]; }); } else { dnsInputs.forEach(input => { input.value = ''; }); } }); function generateONC() { logMessage("Generation started"); let inputDataElements = document.querySelectorAll(".inputData"); let onc = { Type: "UnencryptedConfiguration", NetworkConfigurations: [] }; inputDataElements.forEach(inputDataElement => { try { logMessage(`Checking input field: ${inputDataElement.id}`); let network = JSON.parse(inputDataElement.value); if (!network.GUID || !network.Name || !network.WiFi) { throw new Error("Invalid network data"); } logMessage(`Valid network data found: GUID=${network.GUID}, Name=${network.Name}`); let configuration = { GUID: network.GUID, Metered: document.querySelector("#meteredToggle").checked, Name: network.Name, Type: "WiFi", WiFi: { AutoConnect: true, SSID: network.Name, Security: "None", }, }; if (document.querySelector("#dnsEnabled").checked) { logMessage("DNS Edit enabled. Configuring DNS settings."); let nameServers = []; ["#dns1", "#dns2", "#dns3", "#dns4"].forEach(dnsSelector => { let element = document.querySelector(dnsSelector); nameServers.push(element.value === "" ? "0.0.0.0" : element.value); }); logMessage(`DNS Servers: ${nameServers.join(", ")}`); configuration.NameServersConfigType = "Static"; configuration.StaticIPConfig = { NameServers: nameServers }; } else { logMessage("DNS Edit disabled."); configuration.NameServersConfigType = "DHCP"; } if (document.querySelector("#proxyEnabled").checked) { logMessage("Proxy Edit enabled. Configuring proxy settings."); let parsedExcludeList; try { parsedExcludeList = JSON.parse(document.querySelector("#excludeDomains").value); logMessage(`Exclude Domains: ${JSON.stringify(parsedExcludeList)}`); } catch (e) { logMessage("Failed to parse exclude domains list for proxy", 'error'); parsedExcludeList = []; } configuration.ProxySettings = { ExcludeDomains: parsedExcludeList, Manual: { FTPProxy: { Host: document.querySelector("#ftpProxy").value, Port: parseInt(document.querySelector("#ftpProxyPort").value) }, HTTPProxy: { Host: document.querySelector("#httpProxy").value, Port: parseInt(document.querySelector("#httpProxyPort").value) }, SOCKS: { Host: document.querySelector("#socks").value, Port: parseInt(document.querySelector("#socksProxyPort").value) }, SecureHTTPProxy: { Host: document.querySelector("#secureHttpProxy").value, Port: parseInt(document.querySelector("#secureHttpProxyPort").value) } }, Type: "Manual" }; } else { logMessage("Proxy Edit disabled."); configuration.ProxySettings = { Type: "Direct" }; } onc.NetworkConfigurations.push(configuration); inputDataElement.style.borderColor = "lime"; logMessage(`Configuration added for network: ${network.Name}`); } catch (error) { console.error(error); inputDataElement.style.borderColor = "red"; logMessage(`Error processing input: ${error.message}`, 'error'); } }); if (onc.NetworkConfigurations[0]) { oncData = onc; logMessage("ONC file generation complete. Ready for download."); } else { logMessage("No valid configurations found."); } } function downloadONC() { if (oncData) { logMessage("Downloading ONC file..."); let link = document.createElement("a"); link.href = URL.createObjectURL(new Blob([JSON.stringify(oncData)])); link.download = "network.onc"; link.click(); link.remove(); logMessage("ONC file download triggered."); } else { logMessage("No ONC data available for download. Please generate ONC file first.", 'error'); } } function copyLog() { const logContent = document.querySelector("#logContent").textContent; navigator.clipboard.writeText(logContent).then(() => { logMessage("Log copied to clipboard."); }).catch(err => { logMessage("Failed to copy log to clipboard.", 'error'); }); } document.querySelector("#meteredToggle").addEventListener('change', function() { logMessage(`Metered Toggle ${this.checked ? 'enabled' : 'disabled'}`); }); document.querySelector("#dnsEnabled").addEventListener('change', function() { logMessage(`DNS Edit ${this.checked ? 'enabled' : 'disabled'}`); }); document.querySelector("#proxyEnabled").addEventListener('change', function() { logMessage(`Proxy Edit ${this.checked ? 'enabled' : 'disabled'}`); }); document.querySelectorAll("input[type='text'], input[type='number']").forEach(input => { input.addEventListener('change', function() { logMessage(`Input changed: ${this.id} = ${this.value}`); }); }); document.querySelectorAll("input[type='checkbox']").forEach(checkbox => { checkbox.addEventListener('change', function() { logMessage(`Checkbox changed: ${this.id} = ${this.checked}`); }); }); </script> </body> </html>