js-waku/src/lib/discovery/dns_over_https.ts

64 lines
1.5 KiB
TypeScript
Raw Normal View History

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;
}
}