您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This script will check and add TLDs from HaGeZi Most Abused TLDs (Aggressive) list and allowlist to your NextDNS profile when you visit the profile page. The process can be checked in the browser console.
// ==UserScript== // @name HaGeZi Most Abused TLDs to NextDNS // @namespace vietthe.dev // @match https://my.nextdns.io/* // @grant none // @version 1.0.4 // @license MIT // @author Salad // @compatible firefox Violentmonkey // @compatible firefox Tampermonkey // @compatible firefox FireMonkey // @compatible chrome Violentmonkey // @compatible chrome Tampermonkey // @compatible opera Violentmonkey // @compatible opera Tampermonkey // @compatible safari Stay // @compatible edge Violentmonkey // @compatible edge Tampermonkey // @compatible brave Violentmonkey // @compatible brave Tampermonkey // @description This script will check and add TLDs from HaGeZi Most Abused TLDs (Aggressive) list and allowlist to your NextDNS profile when you visit the profile page. The process can be checked in the browser console. // @icon data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAFOklEQVRogbXaXaicRxkH8N/sJmnSlOZIDC1CJRCseETFK72qFBpFvJQUpAptFdorL0pKkV540AvxQm8sokdsY6ISjNVCxSBUiSLRoq0XYpEqGGmbUGxPTmKO52N35/Fi93zsnvdrPzIw7Owzzzzz/z/zzLwz77zJzUgL0TLvsDV3oKfnigddk1LMuqvWrA2CY+6x7qzkT3hR26IfmL8ZXaWZWzwTn8ZTuENIAiEL/xQ+4+H08iy7mx2Bp+OIPb4geVI4aDNYYpD75beFx6x4zhfT9Vl0Oz2BZ2JO23E8LNyLW0rA93NyXfYLnHLI792fVqfpfnICp+Og5H7hIXxIuL0UdHH5LbyoZ9H7/NK9qTsJjAoCkTzvgGWHtOyT7ZW8U/JB4T7huDDXEOxweff/K8J5PRdkf9N2TdbBumXXLKS18Qn8KD6BE/iA7DDmMCe0xwZcDX5YRkd2VVgW/iP7M844mV5qTuCH8ajkq8JhMdAZ7qQZ6NyAyKjOqDzLuIzPeTxdqCdwOj4ieU5yZ4F3xvfwaF2ZrE6e/V1y3BPp9Z1whx9kC7FH8knhiDzwQoz8VpXr6spkVfLt/G49x42kYQLz9uOY0N5iv2l8NBeBHRd8kZ2iNj2EA8IxJ6K9E/KeEULtgWI/jRMelMfzOOFSXp9kt3qH1oBSAYEVaUs27iozC/BldrZz27uG5+0wgX2SDa3K1WMWICcB369vu1pFYFWStG7aSjJuKO2uS94zhHjXHCAGBMYBT/16Pj34PralqhFYk9wibc3+nUaqQE4aElGgU01q13NrmMB+oTswebNCosoJuUKnn7NLVQQ2hKQ781AZZ7Sq7CRdR7c0Cgi0ZV0bMwdfpLMpG8/O+g6tAgIHdF23OnWoVOnsBNpk1LbbBFarCSzrym5IDUDWdTwt+FGd/q70hoVUQWBJx5yrQtg+kE8Wy+NO5HqdDWHZSBrZjaYsW5L1SjdWUSJvstuMCXX65Q3J26MEdj/IuCJbE25r7LEmYVVmp4n9ft2acKWeQM9lYVW4bQzjTSZhuW4z+arwRj2BrktaVoQjM/d2k/qyNsmSjsujcHe/WvyXN2SvV56OymJ4+ABSd8Iqb1vc30WLqVNPYDF1ZL8unWDTgi+byGWTd1t+fhfWQgLQ8/OhlajOm+OuMKOAy+TbsiXrftOcQPZX2Uu1Ht+Zy4e+2NtFI1W+hJ51qvjlVjGB/vPgO3olwKYFWQV+d7iuyE4X4iwlAD0vyF6p9FLR6JSF06i8rrydL2j5x/gE9npTeFbWaTxJm8qL7BTpcEN41l27txCbqfrt9JfibuFXsqMMDNPsuVCmX9Reaf1FLZ9yKpUSqL5i+lp6Vfb1rVEo8lLRsNeF0GjbYof8FyerwNcTgGXfF87I8kThUka8uryq5ytOpz/UwasnsJg6woLsd7Ugy1eScSZyFn5i3fdqsRnnhuax+KiuU8J7G8dzVXwXl0O4KDzgx+nfTWA1v2b9Zvqj8Ijwl6GVZLpQGfY854WHmoJnkjuyR2Jey7eFe+w8tTGp16EnnNXxhHNp15a5Ko1/0f3d9IrwgOynspXa1aR+tVmSfcucR8cFzzS3lCfigDmfHYTVh0XBO9Wd/43I6Ai/xVPu9vzoYb1pmu6eeCFaXnOX8HnZSQZ3C1XA+79vCl+238884y0m/4Zidjf1D8ZR2ZP4uHAn9o2A/p/+kfCcjm84l5Zm0e1sv5U4EW0Hzeu5T/YxvF/o4mXZBXu94IxL03h8NM3+Yw/6oXXJ7TYckmW3Wva0G7MEvpn+DxZzjNuWWt/KAAAAAElFTkSuQmCC // ==/UserScript== /* jshint esversion:2020 */ (async () => { const apiHost = "https://api.nextdns.io" const invalidTlds = ["non"] const sleep = (ms = 500) => new Promise((resolve) => setTimeout(() => resolve(), ms)) const toHex = (text) => { let hex = '' for (let i = 0; i < text.length; i++) { const charCode = text.charCodeAt(i) const hexCode = charCode.toString(16).padStart(2, '0') hex += hexCode } return hex; } const callApi = (path, options) => fetch(`${apiHost}${path}`, { headers: { "Content-Type": "application/json", ...options?.headers, }, mode: "cors", credentials: "include", ...options, }) const getSecurity = (profileId) => callApi(`/profiles/${profileId}/security`).then((res) => res.json()) const getAllowlist = (profileId) => callApi(`/profiles/${profileId}/allowlist`).then((res) => res.json()) const getAbusedTlds = async () => { const content = await fetch("https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/spam-tlds-adblock-aggressive.txt").then(res => res.text()) const tlds = content.trim().match(/^\|\|(xn--)?\w+\^$/gm).map((e) => e.slice(2, -1)) return tlds } const getTldAllowlist = async () => { const content = await fetch("https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/spam-tlds-adblock-allow.txt").then(res => res.text()) const domains = content.trim().split("\n").map((e) => e.slice(4, -1)) return domains } const addTld = (profileId, tld) => callApi(`/profiles/${profileId}/security/tlds`, { method: "POST", body: JSON.stringify({ id: tld }), }) const removeTld = (profileId, tld) => callApi(`/profiles/${profileId}/security/tlds/hex:${toHex(tld)}`, { method: "DELETE", }) const allowlistDomain = (profileId, domain) => callApi(`/profiles/${profileId}/allowlist`, { method: "POST", body: JSON.stringify({ active: true, id: domain }), }) const run = async (profileId) => { const currentTlds = (await getSecurity(profileId)).data.tlds.map(({ id }) => id) const currentAllowlist = (await getAllowlist(profileId)).data.map(({ id }) => id) const tlds = await getAbusedTlds(profileId) const tldAllowlist = await getTldAllowlist(profileId) const tldsToAdd = tlds.filter((e) => !currentTlds.includes(e) && !invalidTlds.includes(e)) const domainsToAllowlist = tldAllowlist.filter((e) => !currentAllowlist.includes(e)) let index = 1 console.info({ currentTlds, currentAllowlist, tldsToAdd, domainsToAllowlist }) for (const tld of tldsToAdd) { console.info(`Adding .${tld} to TLD blocklist (${index}/${tldsToAdd.length})`) await addTld(profileId, tld) await sleep() index++ } index = 1 for (const domain of domainsToAllowlist) { console.info(`Adding ${domain} to allowlist (${index}/${domainsToAllowlist.length})`) await allowlistDomain(profileId, domain) await sleep() index++ } } const onUrlChange = async () => { if (location.pathname.split("/").length < 3) return console.info("HaGeZi Most Abused TLDs to NextDNS is running...") await run(location.pathname.split("/")[1]) console.info("Done.") } navigation.addEventListener("navigatesuccess", onUrlChange) onUrlChange() })()