2018-05-13 13:51:04 +00:00
|
|
|
import * as plugins from './dnsly.plugins';
|
2016-11-15 20:39:21 +00:00
|
|
|
|
2019-01-06 23:28:15 +00:00
|
|
|
export type TDnsProvider = 'google' | 'cloudflare';
|
2018-05-13 13:51:04 +00:00
|
|
|
export type TDnsRecordType =
|
|
|
|
| 'A'
|
2017-07-18 13:45:06 +00:00
|
|
|
| 'AAAA'
|
|
|
|
| 'CNAME'
|
|
|
|
| 'PTR'
|
|
|
|
| 'MX'
|
|
|
|
| 'NAPTR'
|
|
|
|
| 'NS'
|
|
|
|
| 'SOA'
|
|
|
|
| 'SRV'
|
2018-05-13 13:51:04 +00:00
|
|
|
| 'TXT';
|
2016-11-15 20:39:21 +00:00
|
|
|
|
2017-01-26 23:11:13 +00:00
|
|
|
export interface IDnsRecord {
|
2018-05-13 13:51:04 +00:00
|
|
|
chunked?: string[];
|
|
|
|
name: string;
|
|
|
|
type: TDnsRecordType;
|
|
|
|
value: string;
|
2017-01-26 23:11:13 +00:00
|
|
|
}
|
|
|
|
|
2016-11-15 20:39:21 +00:00
|
|
|
/**
|
|
|
|
* class dnsly offers methods for working with dns from a dns provider like Google DNS
|
|
|
|
*/
|
2018-05-13 13:51:04 +00:00
|
|
|
export class Smartdns {
|
|
|
|
dnsServerIp: string;
|
|
|
|
dnsServerPort: number;
|
2017-07-18 13:45:06 +00:00
|
|
|
/**
|
|
|
|
* constructor for class dnsly
|
|
|
|
*/
|
2019-01-06 23:28:15 +00:00
|
|
|
constructor(dnsProviderArg: TDnsProvider = 'cloudflare') {
|
2018-05-13 13:51:04 +00:00
|
|
|
this._setDnsProvider(dnsProviderArg);
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2016-11-15 20:39:21 +00:00
|
|
|
|
2018-05-13 14:43:46 +00:00
|
|
|
/**
|
|
|
|
* check a dns record until it has propagated to Google DNS
|
|
|
|
* should be considerably fast
|
2019-01-06 23:21:15 +00:00
|
|
|
* @param recordNameArg
|
|
|
|
* @param recordTypeArg
|
|
|
|
* @param expectedValue
|
2018-05-13 14:43:46 +00:00
|
|
|
*/
|
2018-05-13 13:51:04 +00:00
|
|
|
async checkUntilAvailable(
|
|
|
|
recordNameArg: string,
|
|
|
|
recordTypeArg: TDnsRecordType,
|
|
|
|
expectedValue: string
|
|
|
|
) {
|
|
|
|
let cycleArg = 0;
|
2017-07-18 13:45:06 +00:00
|
|
|
let doCheck = async () => {
|
|
|
|
if (cycleArg < 30) {
|
2018-05-13 13:51:04 +00:00
|
|
|
cycleArg++;
|
2017-07-18 13:45:06 +00:00
|
|
|
try {
|
2018-05-13 13:51:04 +00:00
|
|
|
let myRecordArray = await this.getRecord(recordNameArg, recordTypeArg);
|
2018-05-13 14:43:46 +00:00
|
|
|
let myRecord = myRecordArray[0].value[0];
|
2017-07-18 13:45:06 +00:00
|
|
|
if (myRecord === expectedValue) {
|
2018-05-13 13:51:04 +00:00
|
|
|
return true;
|
2017-07-18 13:45:06 +00:00
|
|
|
} else {
|
2019-01-06 23:21:15 +00:00
|
|
|
await plugins.smartdelay.delayFor(2000);
|
2018-05-13 13:51:04 +00:00
|
|
|
return await doCheck();
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
|
|
|
} catch (err) {
|
2019-01-06 23:21:15 +00:00
|
|
|
await plugins.smartdelay.delayFor(2000);
|
2018-05-13 13:51:04 +00:00
|
|
|
return await doCheck();
|
2017-01-26 23:11:13 +00:00
|
|
|
}
|
2017-07-18 13:45:06 +00:00
|
|
|
} else {
|
2018-05-13 13:51:04 +00:00
|
|
|
console.log('failed permanently...');
|
|
|
|
return false;
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2018-05-13 13:51:04 +00:00
|
|
|
};
|
|
|
|
return await doCheck();
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2017-01-26 23:11:13 +00:00
|
|
|
|
2017-07-18 13:45:06 +00:00
|
|
|
/**
|
|
|
|
* get A Dns Record
|
|
|
|
*/
|
2018-05-13 13:51:04 +00:00
|
|
|
async getRecordA(recordNameArg: string): Promise<IDnsRecord[]> {
|
|
|
|
return await this.getRecord(recordNameArg, 'A');
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2017-01-26 23:11:13 +00:00
|
|
|
|
2017-07-18 13:45:06 +00:00
|
|
|
/**
|
|
|
|
* get AAAA Record
|
|
|
|
*/
|
2018-05-13 13:51:04 +00:00
|
|
|
async getRecordAAAA(recordNameArg: string) {
|
|
|
|
return await this.getRecord(recordNameArg, 'AAAA');
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2017-01-26 23:11:13 +00:00
|
|
|
|
2017-07-18 13:45:06 +00:00
|
|
|
/**
|
|
|
|
* gets a txt record
|
|
|
|
*/
|
2018-05-13 13:51:04 +00:00
|
|
|
getRecordTxt(recordNameArg: string): Promise<IDnsRecord[]> {
|
2019-01-06 23:21:15 +00:00
|
|
|
let done = plugins.smartpromise.defer<IDnsRecord[]>();
|
2017-07-18 13:45:06 +00:00
|
|
|
plugins.dns.resolveTxt(recordNameArg, (err, recordsArg) => {
|
|
|
|
if (err) {
|
2018-05-13 13:51:04 +00:00
|
|
|
done.reject(err);
|
|
|
|
return;
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2018-05-13 13:51:04 +00:00
|
|
|
let responseArray: IDnsRecord[] = [];
|
2017-07-18 13:45:06 +00:00
|
|
|
for (let record of recordsArg) {
|
2018-05-13 13:51:04 +00:00
|
|
|
let recordAny: any = record; // fix wrong typings
|
2017-07-18 13:45:06 +00:00
|
|
|
responseArray.push({
|
|
|
|
chunked: recordAny,
|
|
|
|
name: recordNameArg,
|
|
|
|
value: recordAny.join(' '),
|
|
|
|
type: 'TXT'
|
2018-05-13 13:51:04 +00:00
|
|
|
});
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2018-05-13 13:51:04 +00:00
|
|
|
done.resolve(responseArray);
|
|
|
|
});
|
|
|
|
return done.promise;
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2017-01-26 23:11:13 +00:00
|
|
|
|
2017-07-18 13:45:06 +00:00
|
|
|
/**
|
|
|
|
* get oridinary record
|
|
|
|
*/
|
2018-05-13 13:51:04 +00:00
|
|
|
getRecord(recordNameArg: string, recordTypeArg: TDnsRecordType): Promise<IDnsRecord[]> {
|
2019-01-06 23:21:15 +00:00
|
|
|
let done = plugins.smartpromise.defer<IDnsRecord[]>();
|
2017-07-18 13:45:06 +00:00
|
|
|
plugins.dns.resolve(recordNameArg, recordTypeArg, (err, recordsArg) => {
|
|
|
|
if (err) {
|
2018-05-13 13:51:04 +00:00
|
|
|
done.reject(err);
|
|
|
|
return;
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2018-05-13 13:51:04 +00:00
|
|
|
let responseArray: IDnsRecord[] = [];
|
2017-07-18 13:45:06 +00:00
|
|
|
for (let recordKey in recordsArg) {
|
|
|
|
responseArray.push({
|
|
|
|
name: recordNameArg,
|
|
|
|
value: recordsArg[recordKey],
|
|
|
|
type: recordTypeArg
|
2018-05-13 13:51:04 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
done.resolve(responseArray);
|
|
|
|
});
|
|
|
|
return done.promise;
|
|
|
|
}
|
|
|
|
|
|
|
|
getNameServer(domainNameArg: string) {
|
2019-01-06 23:21:15 +00:00
|
|
|
const done = plugins.smartpromise.defer();
|
2018-05-13 13:51:04 +00:00
|
|
|
plugins.dns.resolveNs(domainNameArg, (err, result) => {
|
|
|
|
if (!err) {
|
|
|
|
done.resolve(result);
|
|
|
|
} else {
|
|
|
|
console.log(err);
|
|
|
|
done.reject(err);
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2018-05-13 13:51:04 +00:00
|
|
|
});
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2016-11-15 20:39:21 +00:00
|
|
|
|
2017-07-18 13:45:06 +00:00
|
|
|
/**
|
|
|
|
* set the DNS provider
|
|
|
|
*/
|
2018-05-13 13:51:04 +00:00
|
|
|
private _setDnsProvider(dnsProvider: TDnsProvider) {
|
2017-07-18 13:45:06 +00:00
|
|
|
if (dnsProvider === 'google') {
|
2018-05-13 13:51:04 +00:00
|
|
|
this.dnsServerIp = '8.8.8.8';
|
|
|
|
this.dnsServerPort = 53;
|
|
|
|
plugins.dns.setServers(['8.8.8.8', '8.8.4.4']);
|
2019-01-06 23:28:15 +00:00
|
|
|
} else if (dnsProvider === 'cloudflare') {
|
|
|
|
this.dnsServerIp = '1.1.1.1';
|
|
|
|
this.dnsServerPort = 53;
|
|
|
|
plugins.dns.setServers(['1.1.1.1', '1.0.0.1']);
|
2017-07-18 13:45:06 +00:00
|
|
|
} else {
|
2018-05-13 13:51:04 +00:00
|
|
|
throw new Error('unknown dns provider');
|
2016-11-15 20:39:21 +00:00
|
|
|
}
|
2017-07-18 13:45:06 +00:00
|
|
|
}
|
2017-01-26 23:11:13 +00:00
|
|
|
}
|