2022-02-04 14:12:00 +11:00
|
|
|
import { TxtAnswer } from "dns-packet";
|
2022-01-13 11:33:26 +11:00
|
|
|
import {
|
|
|
|
|
endpoints as defaultEndpoints,
|
|
|
|
|
Endpoint,
|
|
|
|
|
EndpointProps,
|
|
|
|
|
query,
|
2022-02-04 14:12:00 +11:00
|
|
|
} from "dns-query";
|
2022-01-13 11:33:26 +11:00
|
|
|
|
2022-02-16 14:08:48 +11:00
|
|
|
import { bytesToUtf8 } from "../utf8";
|
|
|
|
|
|
2022-02-04 14:12:00 +11:00
|
|
|
import { DnsClient } from "./dns";
|
2022-01-13 11:33:26 +11:00
|
|
|
|
|
|
|
|
const { cloudflare, google, opendns } = defaultEndpoints;
|
|
|
|
|
|
|
|
|
|
export type Endpoints =
|
2022-02-04 14:12:00 +11:00
|
|
|
| "doh"
|
|
|
|
|
| "dns"
|
2022-01-13 11:33:26 +11:00
|
|
|
| Iterable<Endpoint | EndpointProps | string>;
|
|
|
|
|
|
|
|
|
|
export class DnsOverHttps implements DnsClient {
|
|
|
|
|
/**
|
|
|
|
|
* Create new Dns-Over-Http DNS client.
|
|
|
|
|
*
|
|
|
|
|
* @param endpoints The endpoints for Dns-Over-Https queries.
|
|
|
|
|
* See [dns-query](https://www.npmjs.com/package/dns-query) for details.
|
2022-01-13 16:04:07 +11:00
|
|
|
* Defaults to cloudflare, google and opendns.
|
2022-01-13 11:33:26 +11:00
|
|
|
*
|
|
|
|
|
* @throws {code: string} If DNS query fails.
|
|
|
|
|
*/
|
|
|
|
|
public constructor(
|
|
|
|
|
public endpoints: Endpoints = [cloudflare, google, opendns]
|
|
|
|
|
) {}
|
|
|
|
|
|
|
|
|
|
async resolveTXT(domain: string): Promise<string[]> {
|
|
|
|
|
const response = await query({
|
2022-02-04 14:12:00 +11:00
|
|
|
questions: [{ type: "TXT", name: domain }],
|
2022-01-13 11:33:26 +11:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const answers = response.answers as TxtAnswer[];
|
|
|
|
|
|
|
|
|
|
const data = answers.map((a) => a.data);
|
|
|
|
|
|
|
|
|
|
const result: string[] = [];
|
|
|
|
|
|
|
|
|
|
data.forEach((d) => {
|
2022-02-04 14:12:00 +11:00
|
|
|
if (typeof d === "string") {
|
2022-01-13 11:33:26 +11:00
|
|
|
result.push(d);
|
|
|
|
|
} else if (Array.isArray(d)) {
|
|
|
|
|
d.forEach((sd) => {
|
2022-02-04 14:12:00 +11:00
|
|
|
if (typeof sd === "string") {
|
2022-01-13 11:33:26 +11:00
|
|
|
result.push(sd);
|
|
|
|
|
} else {
|
2022-02-16 14:08:48 +11:00
|
|
|
result.push(bytesToUtf8(sd));
|
2022-01-13 11:33:26 +11:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
} else {
|
2022-02-16 14:08:48 +11:00
|
|
|
result.push(bytesToUtf8(d));
|
2022-01-13 11:33:26 +11:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|