diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 3da6a5e0..8235ab10 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -155,6 +155,7 @@ "name": "Networking", "ops": [ "HTTP request", + "DNS over HTTPS", "Strip HTTP headers", "Dechunk HTTP response", "Parse User Agent", diff --git a/src/core/operations/DNSOverHTTPS.mjs b/src/core/operations/DNSOverHTTPS.mjs new file mode 100644 index 00000000..2cac79bf --- /dev/null +++ b/src/core/operations/DNSOverHTTPS.mjs @@ -0,0 +1,127 @@ +/** + * @author h345983745 [] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ +import Operation from "../Operation"; +import OperationError from "../errors/OperationError"; + +/** + * HTTPS Over DNS operation + */ +class HTTPSOverDNS extends Operation { + + /** + * HTTPSOverDNS constructor + */ + constructor() { + super(); + + this.name = "DNS over HTTPS"; + this.module = "Default"; + this.description = ["Takes a single domain name and performs a DNS lookup using DNS over HTTPS.", + "

", + "By default, Cloudflare and Google DNS over HTTPS services are supported.", + "

", + "Can be used with any service that supports the GET parameters name and type."].join("\n"); + this.infoURL = "https://en.wikipedia.org/wiki/DNS_over_HTTPS"; + this.inputType = "string"; + this.outputType = "JSON"; + this.manualBake = true; + this.args = [ + { + name: "Resolver", + type: "editableOption", + value: [ + { + name: "Google", + value: "https://dns.google.com/resolve" + }, + { + name: "Cloudflare", + value: "https://cloudflare-dns.com/dns-query" + } + ] + }, + { + name: "Request Type", + type: "option", + value: [ + "A", + "AAAA", + "TXT", + "MX", + "DNSKEY", + "NS" + ] + }, + { + name: "Answer Data Only", + type: "boolean", + value: false + }, + { + name: "Validate DNSSEC", + type: "boolean", + value: true + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {JSON} + */ + run(input, args) { + const [resolver, requestType, justAnswer, DNSSEC] = args; + let url = URL; + try { + url = new URL(resolver); + } catch (error) { + throw new OperationError(error.toString() + + "\n\nThis error could be caused by one of the following:\n" + + " - An invalid Resolver URL\n"); + } + const params = {name: input, type: requestType, cd: DNSSEC}; + + url.search = new URLSearchParams(params); + + return fetch(url, {headers: {"accept": "application/dns-json"}}).then(response => { + return response.json(); + }) + .then(data => { + if (justAnswer) { + return this.extractData(data.Answer); + } + return data; + + }).catch(e => { + throw new OperationError("Error making request to : " + url + "\n" + + "Error Message: " + e.toString()); + }); + + } + + + /** + * Construct an array of just data from a DNS Answer section + * @private + * @param {JSON} data + * @returns {JSON} + */ + extractData(data) { + if (typeof(data) == "undefined"){ + return []; + } else { + const dataValues = []; + data.forEach(element => { + dataValues.push(element.data); + }); + return dataValues; + + } + } +} + +export default HTTPSOverDNS;