Compare commits
88 Commits
Author | SHA1 | Date | |
---|---|---|---|
2cfecab96f | |||
7eb8a46c7c | |||
c56e732d6d | |||
aff5f2e7d9 | |||
6c38ff36d7 | |||
b45cda5084 | |||
dedd3a3f82 | |||
f2dffb6e88 | |||
2a1fbeb183 | |||
a6a47d2e96 | |||
84ad6bbcd6 | |||
4102c3a692 | |||
6281ab0c80 | |||
622c65291e | |||
dd8c97b99a | |||
9c56dc51e3 | |||
45cbd3a953 | |||
d3e2655212 | |||
e02b2253f5 | |||
862577745d | |||
ca72206ab4 | |||
0221c3207e | |||
f2b8fa57af | |||
e5b072d99b | |||
97c57b2865 | |||
e04485231d | |||
228bc88d60 | |||
811041b036 | |||
a1203366d7 | |||
0deb77cda8 | |||
ed8b7ec65a | |||
6cfc12f83f | |||
efd9bbb77a | |||
b463aea274 | |||
c8cf590a5a | |||
42f679ef61 | |||
0cb882bb7d | |||
66f817cdf8 | |||
5925c882c8 | |||
6f09a82eee | |||
e23579709a | |||
929e4152d3 | |||
d0527affc2 | |||
f2ebaf74d9 | |||
b6d8c36f3e | |||
587600d571 | |||
17f293ca4e | |||
0ed946ee63 | |||
e720d5905e | |||
6286bfaa8f | |||
9390bbae61 | |||
ebb007bcdb | |||
e6d99d5664 | |||
7b29efc398 | |||
64c381d42f | |||
d4dbf4f2b3 | |||
562dca35a7 | |||
2bbbbc17e8 | |||
4ada87a945 | |||
3e45a24750 | |||
96b4926f8f | |||
b0ceeda2b9 | |||
b118419301 | |||
25699ebfc5 | |||
a69f565cf8 | |||
fe423a8e8a | |||
70862850d5 | |||
31ab725d2f | |||
d98890c14e | |||
5327914895 | |||
5bd2b6cb55 | |||
1cdce1b862 | |||
e18e7a04ee | |||
e64fa93dca | |||
1cf09016df | |||
aaa218003e | |||
db9d748f99 | |||
40e412282c | |||
768cf06e0e | |||
bab5cea49f | |||
46aa545324 | |||
2ef01e1111 | |||
0f129262e9 | |||
8e4d40edd0 | |||
f6afe90a63 | |||
a6d77bcd9d | |||
f7a6604637 | |||
1ff6902cb3 |
22
.gitignore
vendored
22
.gitignore
vendored
@ -1,4 +1,20 @@
|
|||||||
node_modules/
|
.nogit/
|
||||||
pages/
|
|
||||||
public/
|
# artifacts
|
||||||
coverage/
|
coverage/
|
||||||
|
public/
|
||||||
|
pages/
|
||||||
|
|
||||||
|
# installs
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# caches
|
||||||
|
.yarn/
|
||||||
|
.cache/
|
||||||
|
.rpt2_cache
|
||||||
|
|
||||||
|
# builds
|
||||||
|
dist/
|
||||||
|
dist_*/
|
||||||
|
|
||||||
|
# custom
|
@ -1,59 +0,0 @@
|
|||||||
image: hosttoday/ht-docker-node:npmts
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- test
|
|
||||||
- release
|
|
||||||
- trigger
|
|
||||||
- pages
|
|
||||||
|
|
||||||
testLEGACY:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci test legacy
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
testLTS:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci test lts
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
testSTABLE:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci test stable
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
release:
|
|
||||||
stage: release
|
|
||||||
script:
|
|
||||||
- npmci publish
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
stage: trigger
|
|
||||||
script:
|
|
||||||
- npmci trigger
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
pages:
|
|
||||||
image: hosttoday/ht-docker-node:npmpage
|
|
||||||
stage: pages
|
|
||||||
script:
|
|
||||||
- npmci command npmpage --host gitlab
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
paths:
|
|
||||||
- public
|
|
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"command": "npm test",
|
||||||
|
"name": "Run npm test",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "node-terminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
.vscode/settings.json
vendored
Normal file
26
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"json.schemas": [
|
||||||
|
{
|
||||||
|
"fileMatch": ["/npmextra.json"],
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"npmci": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for npmci"
|
||||||
|
},
|
||||||
|
"gitzone": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "settings for gitzone",
|
||||||
|
"properties": {
|
||||||
|
"projectType": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["website", "element", "service", "npm", "wcc"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
32
README.md
32
README.md
@ -1,32 +0,0 @@
|
|||||||
# dnsly
|
|
||||||
smart dns methods written in TypeScript
|
|
||||||
|
|
||||||
## Availabililty
|
|
||||||
[](https://www.npmjs.com/package/dnsly)
|
|
||||||
[](https://gitlab.com/pushrocks/dnsly)
|
|
||||||
[](https://github.com/pushrocks/dnsly)
|
|
||||||
[](https://pushrocks.gitlab.io/dnsly/)
|
|
||||||
|
|
||||||
## Status for master
|
|
||||||
[](https://gitlab.com/pushrocks/dnsly/commits/master)
|
|
||||||
[](https://gitlab.com/pushrocks/dnsly/commits/master)
|
|
||||||
[](https://david-dm.org/pushrocks/dnsly)
|
|
||||||
[](https://www.bithound.io/github/pushrocks/dnsly/master/dependencies/npm)
|
|
||||||
[](https://www.bithound.io/github/pushrocks/dnsly)
|
|
||||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
|
||||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
|
||||||
[](http://standardjs.com/)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
we recommend the use of TypeScript for optimal intellisense
|
|
||||||
```javascript
|
|
||||||
import * as dnsly from 'dnsly'
|
|
||||||
|
|
||||||
let myDnsly = new dnsly.Dnsly('google') // uses Google DNS Servers e.g 8.8.8.8
|
|
||||||
myDnsly.getRecord('example.com','AAAA') // returns promise
|
|
||||||
.then(record: dnsly.I_AAAA => { // AAAA record for google.com, the I_AAAA will give you proper typings for the record return type
|
|
||||||
// do something
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
[](https://push.rocks)
|
|
4
dist/dnsly.plugins.d.ts
vendored
4
dist/dnsly.plugins.d.ts
vendored
@ -1,4 +0,0 @@
|
|||||||
import 'typings-global';
|
|
||||||
import * as beautylog from 'beautylog';
|
|
||||||
import * as dns from 'dns';
|
|
||||||
export { beautylog, dns };
|
|
7
dist/dnsly.plugins.js
vendored
7
dist/dnsly.plugins.js
vendored
@ -1,7 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
require("typings-global");
|
|
||||||
const beautylog = require("beautylog");
|
|
||||||
exports.beautylog = beautylog;
|
|
||||||
const dns = require("dns");
|
|
||||||
exports.dns = dns;
|
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG5zbHkucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2Ruc2x5LnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBCQUF1QjtBQUN2Qix1Q0FBc0M7QUFJbEMsOEJBQVM7QUFIYiwyQkFBMEI7QUFJdEIsa0JBQUcifQ==
|
|
23
dist/index.d.ts
vendored
23
dist/index.d.ts
vendored
@ -1,23 +0,0 @@
|
|||||||
/// <reference types="q" />
|
|
||||||
import * as q from 'q';
|
|
||||||
export declare type TDnsProvider = 'google';
|
|
||||||
export declare type TDnsRecordType = 'A' | 'AAAA' | 'CNAME' | 'PTR' | 'MX' | 'NAPTR' | 'NS' | 'SOA' | 'SRV' | 'TXT';
|
|
||||||
/**
|
|
||||||
* class dnsly offers methods for working with dns from a dns provider like Google DNS
|
|
||||||
*/
|
|
||||||
export declare class Dnsly {
|
|
||||||
dnsServerIp: string;
|
|
||||||
dnsServerPort: number;
|
|
||||||
/**
|
|
||||||
* constructor for class dnsly
|
|
||||||
*/
|
|
||||||
constructor(dnsProviderArg: TDnsProvider);
|
|
||||||
/**
|
|
||||||
* gets a record
|
|
||||||
*/
|
|
||||||
getRecord(recordNameArg: string, recordTypeArg: TDnsRecordType): q.Promise<{}>;
|
|
||||||
/**
|
|
||||||
* set the DNS provider
|
|
||||||
*/
|
|
||||||
private _setDnsProvider(dnsProvider);
|
|
||||||
}
|
|
42
dist/index.js
vendored
42
dist/index.js
vendored
@ -1,42 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
const q = require("q");
|
|
||||||
const plugins = require("./dnsly.plugins");
|
|
||||||
/**
|
|
||||||
* class dnsly offers methods for working with dns from a dns provider like Google DNS
|
|
||||||
*/
|
|
||||||
class Dnsly {
|
|
||||||
/**
|
|
||||||
* constructor for class dnsly
|
|
||||||
*/
|
|
||||||
constructor(dnsProviderArg) {
|
|
||||||
this._setDnsProvider(dnsProviderArg);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* gets a record
|
|
||||||
*/
|
|
||||||
getRecord(recordNameArg, recordTypeArg) {
|
|
||||||
let done = q.defer();
|
|
||||||
plugins.dns.resolve(recordNameArg, recordTypeArg, (err, addresses) => {
|
|
||||||
if (err) {
|
|
||||||
done.reject(err);
|
|
||||||
}
|
|
||||||
done.resolve(addresses);
|
|
||||||
});
|
|
||||||
return done.promise;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* set the DNS provider
|
|
||||||
*/
|
|
||||||
_setDnsProvider(dnsProvider) {
|
|
||||||
if (dnsProvider === 'google') {
|
|
||||||
this.dnsServerIp = '8.8.8.8';
|
|
||||||
this.dnsServerPort = 53;
|
|
||||||
plugins.dns.setServers(['8.8.8.8', '8.8.4.4']);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error('unknown dns provider');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.Dnsly = Dnsly;
|
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsdUJBQXNCO0FBQ3RCLDJDQUEwQztBQWMxQzs7R0FFRztBQUNIO0lBR0k7O09BRUc7SUFDSCxZQUFZLGNBQTRCO1FBQ3BDLElBQUksQ0FBQyxlQUFlLENBQUMsY0FBYyxDQUFDLENBQUE7SUFDeEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxDQUFDLGFBQXFCLEVBQUUsYUFBNkI7UUFDMUQsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQ3BCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBQyxhQUFhLEVBQUUsQ0FBQyxHQUFHLEVBQUUsU0FBUztZQUM1RCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNOLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDcEIsQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDM0IsQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSyxlQUFlLENBQUMsV0FBeUI7UUFDN0MsRUFBRSxDQUFDLENBQUMsV0FBVyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDM0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUE7WUFDNUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUE7WUFDdkIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxTQUFTLEVBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQTtRQUNqRCxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDSixNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUE7UUFDM0MsQ0FBQztJQUNMLENBQUM7Q0FDSjtBQXBDRCxzQkFvQ0MifQ==
|
|
31
npmextra.json
Normal file
31
npmextra.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"gitzone": {
|
||||||
|
"projectType": "npm",
|
||||||
|
"module": {
|
||||||
|
"githost": "code.foss.global",
|
||||||
|
"gitscope": "push.rocks",
|
||||||
|
"gitrepo": "smartdns",
|
||||||
|
"description": "A TypeScript library for smart DNS methods, supporting various DNS records and providers.",
|
||||||
|
"npmPackagename": "@push.rocks/smartdns",
|
||||||
|
"license": "MIT",
|
||||||
|
"keywords": [
|
||||||
|
"DNS",
|
||||||
|
"TypeScript",
|
||||||
|
"Node.js",
|
||||||
|
"Google DNS",
|
||||||
|
"Cloudflare",
|
||||||
|
"DNS records",
|
||||||
|
"DNS resolution",
|
||||||
|
"DNSSEC"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npmci": {
|
||||||
|
"npmGlobalTools": [],
|
||||||
|
"npmAccessLevel": "public",
|
||||||
|
"npmRegistryUrl": "registry.npmjs.org"
|
||||||
|
},
|
||||||
|
"tsdoc": {
|
||||||
|
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
||||||
|
}
|
||||||
|
}
|
71
package.json
71
package.json
@ -1,37 +1,68 @@
|
|||||||
{
|
{
|
||||||
"name": "dnsly",
|
"name": "@push.rocks/smartdns",
|
||||||
"version": "1.0.3",
|
"version": "6.0.0",
|
||||||
"description": "smart dns methods written in TypeScript",
|
"private": false,
|
||||||
"main": "dist/index.js",
|
"description": "A TypeScript library for smart DNS methods, supporting various DNS records and providers.",
|
||||||
"typings": "../dist/index.d.ts",
|
"exports": {
|
||||||
|
".": "./dist_ts_server/index.js",
|
||||||
|
"./server": "./dist_ts_server/index.js",
|
||||||
|
"./client": "./dist_ts_client/index.js"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(npmts)"
|
"test": "(tstest test/)",
|
||||||
|
"build": "(tsbuild tsfolders --web --allowimplicitany)",
|
||||||
|
"buildDocs": "tsdoc"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+ssh://git@gitlab.com/pushrocks/dnsly.git"
|
"url": "https://code.foss.global/push.rocks/smartdns.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"dns",
|
"DNS",
|
||||||
"google dns",
|
"TypeScript",
|
||||||
"dns record"
|
"Node.js",
|
||||||
|
"Google DNS",
|
||||||
|
"Cloudflare",
|
||||||
|
"DNS records",
|
||||||
|
"DNS resolution",
|
||||||
|
"DNSSEC"
|
||||||
],
|
],
|
||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://gitlab.com/pushrocks/dnsly/issues"
|
"url": "https://gitlab.com/pushrocks/dnsly/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/pushrocks/dnsly#README",
|
"homepage": "https://code.foss.global/push.rocks/smartdns",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/q": "0.0.32",
|
"@push.rocks/smartdelay": "^3.0.1",
|
||||||
"beautylog": "^6.0.0",
|
"@push.rocks/smartenv": "^5.0.5",
|
||||||
"dns-socket": "^1.4.2",
|
"@push.rocks/smartpromise": "^4.0.2",
|
||||||
"q": "^1.4.1",
|
"@push.rocks/smartrequest": "^2.0.15",
|
||||||
"typings-global": "^1.0.14"
|
"@tsclass/tsclass": "^4.0.54",
|
||||||
|
"@types/dns-packet": "^5.6.5",
|
||||||
|
"dns-packet": "^5.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/should": "^8.1.30",
|
"@git.zone/tsbuild": "^2.1.66",
|
||||||
"should": "^11.1.1",
|
"@git.zone/tsrun": "^1.2.44",
|
||||||
"typings-test": "^1.0.3"
|
"@git.zone/tstest": "^1.0.77",
|
||||||
}
|
"@push.rocks/tapbundle": "^5.0.8",
|
||||||
|
"@types/node": "^20.13.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"ts/**/*",
|
||||||
|
"ts_web/**/*",
|
||||||
|
"dist/**/*",
|
||||||
|
"dist_*/**/*",
|
||||||
|
"dist_ts/**/*",
|
||||||
|
"dist_ts_web/**/*",
|
||||||
|
"assets/**/*",
|
||||||
|
"cli.js",
|
||||||
|
"npmextra.json",
|
||||||
|
"readme.md"
|
||||||
|
],
|
||||||
|
"browserslist": [
|
||||||
|
"last 1 chrome versions"
|
||||||
|
],
|
||||||
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
6719
pnpm-lock.yaml
generated
Normal file
6719
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
1
readme.hints.md
Normal file
1
readme.hints.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
124
readme.md
Normal file
124
readme.md
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
# @push.rocks/smartdns
|
||||||
|
|
||||||
|
smart dns methods written in TypeScript
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
To install `@push.rocks/smartdns`, use the following command with npm:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @push.rocks/smartdns --save
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with `yarn`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn add @push.rocks/smartdns
|
||||||
|
```
|
||||||
|
|
||||||
|
Make sure you have a TypeScript environment setup to utilize the library effectively.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
`@push.rocks/smartdns` is a comprehensive library aimed at facilitating smart DNS operations, leveraging TypeScript for enhanced development experience. This section aims to cover several real-world scenarios demonstrating the library's capabilities, from basic DNS lookups to more advanced DNS management tasks.
|
||||||
|
|
||||||
|
### Getting Started
|
||||||
|
|
||||||
|
First, ensure you import the module into your TypeScript project:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { Smartdns } from '@push.rocks/smartdns';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic DNS Record Lookup
|
||||||
|
|
||||||
|
Often, the need arises to fetch various DNS records for a domain. `@push.rocks/smartdns` simplifies this by providing intuitive methods.
|
||||||
|
|
||||||
|
#### Fetching A Records
|
||||||
|
|
||||||
|
To fetch an "A" record for a domain:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const dnsManager = new Smartdns({});
|
||||||
|
const aRecords = await dnsManager.getRecordsA('example.com');
|
||||||
|
console.log(aRecords);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Fetching AAAA Records
|
||||||
|
|
||||||
|
Similarly, for "AAAA" records:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const aaaaRecords = await dnsManager.getRecordsAAAA('example.com');
|
||||||
|
console.log(aaaaRecords);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced DNS Management
|
||||||
|
|
||||||
|
Beyond simple queries, `@push.rocks/smartdns` offers functionalities suitable for more complex DNS management scenarios.
|
||||||
|
|
||||||
|
#### Checking DNS Propagation
|
||||||
|
|
||||||
|
When changing DNS records, ensuring that the new records have propagated fully is crucial. `@push.rocks/smartdns` facilitates this with a method to check a DNS record until it is available globally.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const recordType = 'TXT'; // Record type: A, AAAA, CNAME, TXT etc.
|
||||||
|
const expectedValue = 'your_expected_value';
|
||||||
|
const isAvailable = await dnsManager.checkUntilAvailable('example.com', recordType, expectedValue);
|
||||||
|
|
||||||
|
if (isAvailable) {
|
||||||
|
console.log('Record propagated successfully.');
|
||||||
|
} else {
|
||||||
|
console.log('Record propagation failed or timed out.');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Leveraging DNS for Application Logic
|
||||||
|
|
||||||
|
DNS records can serve beyond mere domain-to-IP resolution; they can be instrumental in application logic, such as feature flagging or environment-specific configurations.
|
||||||
|
|
||||||
|
#### Example: Feature Flagging via TXT Records
|
||||||
|
|
||||||
|
Consider leveraging TXT records for enabling/disabling features dynamically without deploying new code.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const txtRecords = await dnsManager.getRecordsTxt('features.example.com');
|
||||||
|
const featureFlags = txtRecords.reduce((acc, record) => {
|
||||||
|
const [flag, isEnabled] = record.value.split('=');
|
||||||
|
acc[flag] = isEnabled === 'true';
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
if (featureFlags['NewFeature']) {
|
||||||
|
// Logic to enable the new feature
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conclusion
|
||||||
|
|
||||||
|
`@push.rocks/smartdns` offers a versatile set of tools for DNS querying and management, tailored for applications at any scale. The examples provided illustrate the library's potential use cases, highlighting its applicability in various scenarios from basic lookups to facilitating complex application features through DNS.
|
||||||
|
|
||||||
|
For the full spectrum of functionalities, including detailed method documentation and additional use cases, consult the module's [TypeDoc documentation](https://pushrocks.gitlab.io/smartdns/). This will serve as a comprehensive guide to leveraging `@push.rocks/smartdns` effectively in your projects.
|
||||||
|
|
||||||
|
Remember, DNS changes might take time to propagate worldwide, and the utility methods provided by `@push.rocks/smartdns` for checking record availability will be invaluable in managing these changes seamlessly.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## License and Legal Information
|
||||||
|
|
||||||
|
This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository.
|
||||||
|
|
||||||
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
### Trademarks
|
||||||
|
|
||||||
|
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.
|
||||||
|
|
||||||
|
### Company Information
|
||||||
|
|
||||||
|
Task Venture Capital GmbH
|
||||||
|
Registered at District court Bremen HRB 35230 HB, Germany
|
||||||
|
|
||||||
|
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
||||||
|
|
||||||
|
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
79
test/test.client.ts
Normal file
79
test/test.client.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import { expect, tap } from '@push.rocks/tapbundle';
|
||||||
|
|
||||||
|
import * as smartdns from '../ts_client/index.js';
|
||||||
|
|
||||||
|
let testDnsly: smartdns.Smartdns;
|
||||||
|
|
||||||
|
tap.test('should create an instance of Dnsly', async () => {
|
||||||
|
testDnsly = new smartdns.Smartdns({});
|
||||||
|
expect(testDnsly).toBeInstanceOf(smartdns.Smartdns);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should get an A DNS Record', async () => {
|
||||||
|
return expect(await testDnsly.getRecordsA('dnsly_a.bleu.de')).toEqual([
|
||||||
|
{
|
||||||
|
name: 'dnsly_a.bleu.de',
|
||||||
|
value: '127.0.0.1',
|
||||||
|
dnsSecEnabled: false,
|
||||||
|
type: 'A',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should get an AAAA Record', async () => {
|
||||||
|
return expect(await testDnsly.getRecordsAAAA('dnsly_aaaa.bleu.de')).toEqual([
|
||||||
|
{
|
||||||
|
name: 'dnsly_aaaa.bleu.de',
|
||||||
|
value: '::1',
|
||||||
|
dnsSecEnabled: false,
|
||||||
|
type: 'AAAA',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should get a txt record', async () => {
|
||||||
|
return expect(await testDnsly.getRecordsTxt('dnsly_txt.bleu.de')).toEqual([
|
||||||
|
{
|
||||||
|
name: 'dnsly_txt.bleu.de',
|
||||||
|
value: 'sometext_txt',
|
||||||
|
type: 'TXT',
|
||||||
|
dnsSecEnabled: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should, get a mx record for a domain', async () => {
|
||||||
|
const res = await testDnsly.getRecords('bleu.de', 'MX');
|
||||||
|
console.log(res);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should check until DNS is available', async () => {
|
||||||
|
return expect(
|
||||||
|
await testDnsly.checkUntilAvailable('dnsly_txt.bleu.de', 'TXT', 'sometext_txt')
|
||||||
|
).toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should check until DNS is available an return false if it fails', async () => {
|
||||||
|
return expect(
|
||||||
|
await testDnsly.checkUntilAvailable('dnsly_txt.bleu.de', 'TXT', 'sometext_txt2')
|
||||||
|
).toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should check until DNS is available an return false if it fails', async () => {
|
||||||
|
return expect(
|
||||||
|
await testDnsly.checkUntilAvailable('dnsly_txtNotThere.bleu.de', 'TXT', 'sometext_txt2')
|
||||||
|
).toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should get name server for hostname', async () => {
|
||||||
|
let result = await testDnsly.getNameServers('bleu.de');
|
||||||
|
console.log(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should detect dns sec', async () => {
|
||||||
|
const result = await testDnsly.getRecordsA('lossless.com');
|
||||||
|
console.log(result[0]);
|
||||||
|
expect(result[0].dnsSecEnabled).toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.start();
|
1
test/test.d.ts
vendored
1
test/test.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
import 'typings-test';
|
|
30
test/test.js
30
test/test.js
@ -1,30 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
require("typings-test");
|
|
||||||
const should = require("should");
|
|
||||||
const dnsly = require("../dist/index");
|
|
||||||
let testDnsly;
|
|
||||||
describe('dnsly', function () {
|
|
||||||
it('should create an instance of Dnsly', function () {
|
|
||||||
testDnsly = new dnsly.Dnsly('google');
|
|
||||||
should(testDnsly).be.instanceOf(dnsly.Dnsly);
|
|
||||||
});
|
|
||||||
it('should, get a dns record for a domain', function (done) {
|
|
||||||
testDnsly.getRecord('google.com', 'A').then(res => {
|
|
||||||
console.log(res);
|
|
||||||
done();
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it('should, get a mx record for a domain', function (done) {
|
|
||||||
testDnsly.getRecord('google.com', 'MX').then(res => {
|
|
||||||
console.log(res);
|
|
||||||
done();
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
done(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFFaEMsdUNBQXNDO0FBRXRDLElBQUksU0FBc0IsQ0FBQTtBQUUxQixRQUFRLENBQUMsT0FBTyxFQUFFO0lBQ2QsRUFBRSxDQUFDLG9DQUFvQyxFQUFFO1FBQ3JDLFNBQVMsR0FBRyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDckMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2hELENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHVDQUF1QyxFQUFFLFVBQVUsSUFBSTtRQUN0RCxTQUFTLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRztZQUMzQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2hCLElBQUksRUFBRSxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUc7WUFDUixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNiLENBQUMsQ0FBQyxDQUFBO0lBRU4sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsc0NBQXNDLEVBQUUsVUFBVSxJQUFJO1FBQ3JELFNBQVMsQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHO1lBQzVDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDaEIsSUFBSSxFQUFFLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRztZQUNSLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDaEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ2IsQ0FBQyxDQUFDLENBQUE7SUFFTixDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQyxDQUFBIn0=
|
|
0
test/test.server.ts
Normal file
0
test/test.server.ts
Normal file
35
test/test.ts
35
test/test.ts
@ -1,35 +0,0 @@
|
|||||||
import 'typings-test'
|
|
||||||
import * as should from 'should'
|
|
||||||
|
|
||||||
import * as dnsly from '../dist/index'
|
|
||||||
|
|
||||||
let testDnsly: dnsly.Dnsly
|
|
||||||
|
|
||||||
describe('dnsly', function () {
|
|
||||||
it('should create an instance of Dnsly', function () {
|
|
||||||
testDnsly = new dnsly.Dnsly('google')
|
|
||||||
should(testDnsly).be.instanceOf(dnsly.Dnsly)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should, get a dns record for a domain', function (done) {
|
|
||||||
testDnsly.getRecord('google.com', 'A').then(res => {
|
|
||||||
console.log(res)
|
|
||||||
done()
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
done(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should, get a mx record for a domain', function (done) {
|
|
||||||
testDnsly.getRecord('google.com', 'MX').then(res => {
|
|
||||||
console.log(res)
|
|
||||||
done()
|
|
||||||
}).catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
done(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,8 +0,0 @@
|
|||||||
import 'typings-global'
|
|
||||||
import * as beautylog from 'beautylog'
|
|
||||||
import * as dns from 'dns'
|
|
||||||
|
|
||||||
export {
|
|
||||||
beautylog,
|
|
||||||
dns
|
|
||||||
}
|
|
55
ts/index.ts
55
ts/index.ts
@ -1,55 +0,0 @@
|
|||||||
import * as q from 'q'
|
|
||||||
import * as plugins from './dnsly.plugins'
|
|
||||||
|
|
||||||
export type TDnsProvider = 'google'
|
|
||||||
export type TDnsRecordType = 'A'
|
|
||||||
| 'AAAA'
|
|
||||||
| 'CNAME'
|
|
||||||
| 'PTR'
|
|
||||||
| 'MX'
|
|
||||||
| 'NAPTR'
|
|
||||||
| 'NS'
|
|
||||||
| 'SOA'
|
|
||||||
| 'SRV'
|
|
||||||
| 'TXT'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* class dnsly offers methods for working with dns from a dns provider like Google DNS
|
|
||||||
*/
|
|
||||||
export class Dnsly {
|
|
||||||
dnsServerIp: string
|
|
||||||
dnsServerPort: number
|
|
||||||
/**
|
|
||||||
* constructor for class dnsly
|
|
||||||
*/
|
|
||||||
constructor(dnsProviderArg: TDnsProvider) {
|
|
||||||
this._setDnsProvider(dnsProviderArg)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gets a record
|
|
||||||
*/
|
|
||||||
getRecord(recordNameArg: string, recordTypeArg: TDnsRecordType) {
|
|
||||||
let done = q.defer()
|
|
||||||
plugins.dns.resolve(recordNameArg,recordTypeArg, (err, addresses) => {
|
|
||||||
if (err) {
|
|
||||||
done.reject(err)
|
|
||||||
}
|
|
||||||
done.resolve(addresses)
|
|
||||||
})
|
|
||||||
return done.promise
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set the DNS provider
|
|
||||||
*/
|
|
||||||
private _setDnsProvider(dnsProvider: TDnsProvider) {
|
|
||||||
if (dnsProvider === 'google') {
|
|
||||||
this.dnsServerIp = '8.8.8.8'
|
|
||||||
this.dnsServerPort = 53
|
|
||||||
plugins.dns.setServers(['8.8.8.8','8.8.4.4'])
|
|
||||||
} else {
|
|
||||||
throw new Error('unknown dns provider')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
8
ts_client/00_commitinfo_data.ts
Normal file
8
ts_client/00_commitinfo_data.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* autocreated commitinfo by @push.rocks/commitinfo
|
||||||
|
*/
|
||||||
|
export const commitinfo = {
|
||||||
|
name: '@push.rocks/smartdns',
|
||||||
|
version: '5.0.4',
|
||||||
|
description: 'smart dns methods written in TypeScript'
|
||||||
|
}
|
229
ts_client/classes.dnsclient.ts
Normal file
229
ts_client/classes.dnsclient.ts
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
import * as plugins from './dnsly.plugins.js';
|
||||||
|
|
||||||
|
export type TDnsProvider = 'google' | 'cloudflare';
|
||||||
|
|
||||||
|
export const makeNodeProcessUseDnsProvider = (providerArg: TDnsProvider) => {
|
||||||
|
switch (providerArg) {
|
||||||
|
case 'cloudflare':
|
||||||
|
plugins.dns.setServers([
|
||||||
|
'1.1.1.1',
|
||||||
|
'1.0.0.1',
|
||||||
|
'[2606:4700:4700::1111]',
|
||||||
|
'[2606:4700:4700::1001]',
|
||||||
|
]);
|
||||||
|
break;
|
||||||
|
case 'google':
|
||||||
|
plugins.dns.setServers([
|
||||||
|
'8.8.8.8',
|
||||||
|
'8.8.4.4',
|
||||||
|
'[2001:4860:4860::8888]',
|
||||||
|
'[2606:4700:4700::1001]',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface ISmartDnsConstructorOptions {}
|
||||||
|
|
||||||
|
export interface IGoogleDNSHTTPSResponse {
|
||||||
|
Status: number;
|
||||||
|
TC: boolean;
|
||||||
|
RD: boolean;
|
||||||
|
RA: boolean;
|
||||||
|
AD: boolean;
|
||||||
|
CD: boolean;
|
||||||
|
Question: Array<{ name: string; type: number }>;
|
||||||
|
Answer: Array<{ name: string; type: number; TTL: number; data: string }>;
|
||||||
|
Additional: [];
|
||||||
|
Comment: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class dnsly offers methods for working with dns from a dns provider like Google DNS
|
||||||
|
*/
|
||||||
|
export class Smartdns {
|
||||||
|
public dnsServerIp: string;
|
||||||
|
public dnsServerPort: number;
|
||||||
|
|
||||||
|
public dnsTypeMap: { [key: string]: number } = {
|
||||||
|
A: 1,
|
||||||
|
AAAA: 28,
|
||||||
|
CNAME: 5,
|
||||||
|
MX: 15,
|
||||||
|
TXT: 16,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* constructor for class dnsly
|
||||||
|
*/
|
||||||
|
constructor(optionsArg: ISmartDnsConstructorOptions) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check a dns record until it has propagated to Google DNS
|
||||||
|
* should be considerably fast
|
||||||
|
* @param recordNameArg
|
||||||
|
* @param recordTypeArg
|
||||||
|
* @param expectedValue
|
||||||
|
*/
|
||||||
|
public async checkUntilAvailable(
|
||||||
|
recordNameArg: string,
|
||||||
|
recordTypeArg: plugins.tsclass.network.TDnsRecordType,
|
||||||
|
expectedValue: string,
|
||||||
|
cyclesArg: number = 50,
|
||||||
|
intervalArg: number = 500
|
||||||
|
) {
|
||||||
|
let runCycles = 0;
|
||||||
|
const doCheck = async () => {
|
||||||
|
if (runCycles < cyclesArg) {
|
||||||
|
runCycles++;
|
||||||
|
try {
|
||||||
|
let myRecordArray: plugins.tsclass.network.IDnsRecord[];
|
||||||
|
if (runCycles % 2 === 0 || !plugins.dns) {
|
||||||
|
myRecordArray = await this.getRecords(recordNameArg, recordTypeArg, 0);
|
||||||
|
} else {
|
||||||
|
myRecordArray = await this.getRecordWithNodeDNS(recordNameArg, recordTypeArg);
|
||||||
|
}
|
||||||
|
const myRecord = myRecordArray[0].value;
|
||||||
|
if (myRecord === expectedValue) {
|
||||||
|
console.log(
|
||||||
|
`smartdns: .checkUntilAvailable() verified that wanted >>>${recordTypeArg}<<< record exists for >>>${recordNameArg}<<< with value >>>${expectedValue}<<<`
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
await plugins.smartdelay.delayFor(intervalArg);
|
||||||
|
return await doCheck();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// console.log(err);
|
||||||
|
await plugins.smartdelay.delayFor(intervalArg);
|
||||||
|
return await doCheck();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
`smartdns: .checkUntilAvailable() failed permanently for ${recordNameArg} with value ${recordTypeArg} - ${expectedValue}...`
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return await doCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get A Dns Record
|
||||||
|
*/
|
||||||
|
public async getRecordsA(recordNameArg: string): Promise<plugins.tsclass.network.IDnsRecord[]> {
|
||||||
|
return await this.getRecords(recordNameArg, 'A');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get AAAA Record
|
||||||
|
*/
|
||||||
|
public async getRecordsAAAA(recordNameArg: string) {
|
||||||
|
return await this.getRecords(recordNameArg, 'AAAA');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets a txt record
|
||||||
|
*/
|
||||||
|
public async getRecordsTxt(recordNameArg: string): Promise<plugins.tsclass.network.IDnsRecord[]> {
|
||||||
|
return await this.getRecords(recordNameArg, 'TXT');
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getRecords(
|
||||||
|
recordNameArg: string,
|
||||||
|
recordTypeArg: plugins.tsclass.network.TDnsRecordType,
|
||||||
|
retriesCounterArg = 20
|
||||||
|
): Promise<plugins.tsclass.network.IDnsRecord[]> {
|
||||||
|
const requestUrl = `https://cloudflare-dns.com/dns-query?name=${recordNameArg}&type=${recordTypeArg}&do=1`;
|
||||||
|
const returnArray: plugins.tsclass.network.IDnsRecord[] = [];
|
||||||
|
const getResponseBody = async (counterArg = 0): Promise<IGoogleDNSHTTPSResponse> => {
|
||||||
|
const response = await plugins.smartrequest.request(requestUrl, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
accept: 'application/dns-json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const responseBody: IGoogleDNSHTTPSResponse = response.body;
|
||||||
|
if (responseBody?.Status !== 0 && counterArg < retriesCounterArg) {
|
||||||
|
await plugins.smartdelay.delayFor(500);
|
||||||
|
return getResponseBody(counterArg++);
|
||||||
|
} else {
|
||||||
|
return responseBody;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const responseBody = await getResponseBody();
|
||||||
|
if (!responseBody.Answer || !typeof responseBody.Answer[Symbol.iterator]) {
|
||||||
|
return returnArray;
|
||||||
|
}
|
||||||
|
for (const dnsEntry of responseBody.Answer) {
|
||||||
|
if (dnsEntry.data.startsWith('"') && dnsEntry.data.endsWith('"')) {
|
||||||
|
dnsEntry.data = dnsEntry.data.replace(/^"(.*)"$/, '$1');
|
||||||
|
}
|
||||||
|
if (dnsEntry.name.endsWith('.')) {
|
||||||
|
dnsEntry.name = dnsEntry.name.substring(0, dnsEntry.name.length - 1);
|
||||||
|
}
|
||||||
|
returnArray.push({
|
||||||
|
name: dnsEntry.name,
|
||||||
|
type: this.convertDnsTypeNumberToTypeName(dnsEntry.type),
|
||||||
|
dnsSecEnabled: responseBody.AD,
|
||||||
|
value: dnsEntry.data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// console.log(responseBody);
|
||||||
|
return returnArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets a record using nodejs dns resolver
|
||||||
|
*/
|
||||||
|
public async getRecordWithNodeDNS(
|
||||||
|
recordNameArg: string,
|
||||||
|
recordTypeArg: plugins.tsclass.network.TDnsRecordType
|
||||||
|
): Promise<plugins.tsclass.network.IDnsRecord[]> {
|
||||||
|
const done = plugins.smartpromise.defer<plugins.tsclass.network.IDnsRecord[]>();
|
||||||
|
plugins.dns.resolve(recordNameArg, recordTypeArg, (err, recordsArg) => {
|
||||||
|
if (err) {
|
||||||
|
done.reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const returnArray: plugins.tsclass.network.IDnsRecord[] = [];
|
||||||
|
for (const recordKey in recordsArg) {
|
||||||
|
returnArray.push({
|
||||||
|
name: recordNameArg,
|
||||||
|
value: recordsArg[recordKey][0],
|
||||||
|
type: recordTypeArg,
|
||||||
|
dnsSecEnabled: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
done.resolve(returnArray);
|
||||||
|
});
|
||||||
|
return done.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getNameServers(domainNameArg: string): Promise<string[]> {
|
||||||
|
const done = plugins.smartpromise.defer<string[]>();
|
||||||
|
plugins.dns.resolveNs(domainNameArg, (err, result) => {
|
||||||
|
if (!err) {
|
||||||
|
done.resolve(result);
|
||||||
|
} else {
|
||||||
|
console.log(err);
|
||||||
|
done.reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return await done.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public convertDnsTypeNameToTypeNumber(dnsTypeNameArg: string): number {
|
||||||
|
return this.dnsTypeMap[dnsTypeNameArg];
|
||||||
|
}
|
||||||
|
|
||||||
|
public convertDnsTypeNumberToTypeName(
|
||||||
|
dnsTypeNumberArg: number
|
||||||
|
): plugins.tsclass.network.TDnsRecordType {
|
||||||
|
for (const key in this.dnsTypeMap) {
|
||||||
|
if (this.dnsTypeMap[key] === dnsTypeNumberArg) {
|
||||||
|
return key as plugins.tsclass.network.TDnsRecordType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
22
ts_client/dnsly.plugins.ts
Normal file
22
ts_client/dnsly.plugins.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import * as smartenv from '@push.rocks/smartenv';
|
||||||
|
const smartenvInstance = new smartenv.Smartenv();
|
||||||
|
// node native scope
|
||||||
|
import type dnsType from 'dns';
|
||||||
|
const dns: typeof dnsType = await smartenvInstance.getSafeNodeModule('dns');
|
||||||
|
|
||||||
|
export { dns };
|
||||||
|
|
||||||
|
// pushrocks scope
|
||||||
|
import * as smartdelay from '@push.rocks/smartdelay';
|
||||||
|
import * as smartpromise from '@push.rocks/smartpromise';
|
||||||
|
import * as smartrequest from '@push.rocks/smartrequest';
|
||||||
|
|
||||||
|
export { smartdelay, smartenv, smartpromise, smartrequest };
|
||||||
|
|
||||||
|
import * as tsclass from '@tsclass/tsclass';
|
||||||
|
|
||||||
|
export { tsclass };
|
||||||
|
|
||||||
|
// third party scope
|
||||||
|
const dns2 = smartenvInstance.getSafeNodeModule('dns2');
|
||||||
|
export { dns2 };
|
1
ts_client/index.ts
Normal file
1
ts_client/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './classes.dnsclient.js';
|
120
ts_server/classes.dnsserver.ts
Normal file
120
ts_server/classes.dnsserver.ts
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import * as plugins from './plugins.js';
|
||||||
|
|
||||||
|
interface IDnsServerOptions {
|
||||||
|
httpsKey: string;
|
||||||
|
httpsCert: string;
|
||||||
|
httpsPort: number;
|
||||||
|
udpPort: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DnsServer {
|
||||||
|
private udpServer: plugins.dgram.Socket;
|
||||||
|
private httpsServer: plugins.https.Server;
|
||||||
|
|
||||||
|
constructor(private options: IDnsServerOptions) {
|
||||||
|
this.udpServer = plugins.dgram.createSocket('udp4');
|
||||||
|
this.setupUdpServer();
|
||||||
|
|
||||||
|
this.httpsServer = plugins.https.createServer(
|
||||||
|
{
|
||||||
|
key: plugins.fs.readFileSync(options.httpsKey),
|
||||||
|
cert: plugins.fs.readFileSync(options.httpsCert)
|
||||||
|
},
|
||||||
|
this.handleHttpsRequest.bind(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setupUdpServer(): void {
|
||||||
|
this.udpServer.on('message', (msg, rinfo) => {
|
||||||
|
const request = plugins.dnsPacket.decode(msg);
|
||||||
|
const response = {
|
||||||
|
type: 'response' as const,
|
||||||
|
id: request.id,
|
||||||
|
flags: plugins.dnsPacket.RECURSION_DESIRED | plugins.dnsPacket.RECURSION_AVAILABLE,
|
||||||
|
questions: request.questions,
|
||||||
|
answers: [] as plugins.dnsPacket.Answer[]
|
||||||
|
};
|
||||||
|
|
||||||
|
const question = request.questions[0];
|
||||||
|
console.log(`UDP query for ${question.name} of type ${question.type}`);
|
||||||
|
|
||||||
|
if (question.type === 'A') {
|
||||||
|
response.answers.push({
|
||||||
|
name: question.name,
|
||||||
|
type: 'A',
|
||||||
|
class: 'IN',
|
||||||
|
ttl: 300,
|
||||||
|
data: '127.0.0.1'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const responseData = plugins.dnsPacket.encode(response);
|
||||||
|
this.udpServer.send(responseData, rinfo.port, rinfo.address);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.udpServer.on('error', (err) => {
|
||||||
|
console.error(`UDP Server error:\n${err.stack}`);
|
||||||
|
this.udpServer.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.udpServer.bind(this.options.udpPort, '0.0.0.0', () => {
|
||||||
|
console.log(`UDP DNS server running on port ${this.options.udpPort}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleHttpsRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse): void {
|
||||||
|
if (req.method === 'POST' && req.url === '/dns-query') {
|
||||||
|
let body: Buffer[] = [];
|
||||||
|
|
||||||
|
req.on('data', chunk => {
|
||||||
|
body.push(chunk);
|
||||||
|
}).on('end', () => {
|
||||||
|
const msg = Buffer.concat(body);
|
||||||
|
const request = plugins.dnsPacket.decode(msg);
|
||||||
|
const response = {
|
||||||
|
type: 'response' as const,
|
||||||
|
id: request.id,
|
||||||
|
flags: plugins.dnsPacket.RECURSION_DESIRED | plugins.dnsPacket.RECURSION_AVAILABLE,
|
||||||
|
questions: request.questions,
|
||||||
|
answers: [] as plugins.dnsPacket.Answer[]
|
||||||
|
};
|
||||||
|
|
||||||
|
const question = request.questions[0];
|
||||||
|
console.log(`DoH query for ${question.name} of type ${question.type}`);
|
||||||
|
|
||||||
|
if (question.type === 'A') {
|
||||||
|
response.answers.push({
|
||||||
|
name: question.name,
|
||||||
|
type: 'A',
|
||||||
|
class: 'IN',
|
||||||
|
ttl: 300,
|
||||||
|
data: '127.0.0.1'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const responseData = plugins.dnsPacket.encode(response);
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/dns-message' });
|
||||||
|
res.end(responseData);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.writeHead(404);
|
||||||
|
res.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public start(): void {
|
||||||
|
this.httpsServer.listen(this.options.httpsPort, () => {
|
||||||
|
console.log(`DoH server running on port ${this.options.httpsPort}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public stop(): void {
|
||||||
|
this.udpServer.close(() => {
|
||||||
|
console.log('UDP DNS server stopped');
|
||||||
|
});
|
||||||
|
|
||||||
|
this.httpsServer.close(() => {
|
||||||
|
console.log('HTTPS DNS server stopped');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
0
ts_server/index.ts
Normal file
0
ts_server/index.ts
Normal file
17
ts_server/plugins.ts
Normal file
17
ts_server/plugins.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import http from 'http';
|
||||||
|
import https from 'https';
|
||||||
|
import dgram from 'dgram';
|
||||||
|
|
||||||
|
export {
|
||||||
|
fs,
|
||||||
|
http,
|
||||||
|
https,
|
||||||
|
dgram,
|
||||||
|
}
|
||||||
|
|
||||||
|
import * as dnsPacket from 'dns-packet';
|
||||||
|
|
||||||
|
export {
|
||||||
|
dnsPacket
|
||||||
|
}
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"useDefineForClassFields": false,
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "NodeNext",
|
||||||
|
"moduleResolution": "NodeNext",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"verbatimModuleSyntax": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"dist_*/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "tslint-config-standard"
|
|
||||||
}
|
|
Reference in New Issue
Block a user