Skip to content

Commit

Permalink
rf: with deno (#4)
Browse files Browse the repository at this point in the history
* chore: set deno development environment

* feat: rf with deno

* test: getCurrentIP, getDNSIP

* rf: checkIP, getDNSIP

* feat: cli

* doc: add cli help
  • Loading branch information
iugo authored Nov 2, 2022
1 parent 27f4ae7 commit f9d42fc
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
17 changes: 17 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"deno.codeLens.implementations": true,
"deno.codeLens.referencesAllFunctions": true,
"deno.codeLens.references": true,
"deno.codeLens.test": true,
"deno.enable": true,
"deno.config": "./deno.json",
"deno.lint": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[typescript]": {
"editor.defaultFormatter": "denoland.vscode-deno"
},
"editor.formatOnSave": true,
"[sql]": {
"editor.formatOnSave": false
}
}
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,23 @@ A Node.js program use dns.he.net as DDNS service.

## Configuration

```sh
OPTIONS:

-d, --domain
Set domain

-t, --token
Set he.net auth token

--delaytime
Set loop delay time, ms.

-h, --help
```

Set env:

- USEDDNS_DOMAIN
- USEDDNS_HE_TOKEN
- [OPTION] USEDDNS_DELAY_TIME
40 changes: 40 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"compilerOptions": {
"strict": true
},
"lint": {
"files": {
"include": [
"src/",
"mod.ts"
]
},
"rules": {
"tags": [
"recommended"
],
"include": [
"eqeqeq",
"explicit-module-boundary-types",
"no-throw-literal"
],
"exclude": [
"ban-unused-ignore"
]
}
},
"fmt": {
"files": {
"include": [
"src/",
"mod.ts"
]
},
"options": {
"useTabs": false,
"lineWidth": 80,
"indentWidth": 2,
"singleQuote": true
}
}
}
62 changes: 62 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { parse } from 'https://deno.land/[email protected]/flags/mod.ts';
import { checkIP } from './useddns.ts';

const args = parse<
Partial<
{
d: string;
domain: string;
t: string;
token: string;
delaytime: number;
h: boolean;
help: boolean;
}
>
>(
Deno.args,
);

const isHelp = args.h ?? args.help;
if (isHelp) {
console.log(`
OPTIONS:
-d, --domain
Set domain
-t, --token
Set he.net auth token
--delaytime
Set loop delay time, ms.
-h, --help`);
Deno.exit();
}

const domain = args.d ?? args.domain ?? Deno.env.get('USEDDNS_DOMAIN');
const token = args.t ?? args.token ?? Deno.env.get('USEDDNS_HE_TOKEN');
const delay = Number(
args.delaytime ?? Deno.env.get('USEDDNS_DELAY_TIME') ?? 5000,
);

if (!domain || !token) {
throw new Error(
'Please set cli args or configure environment variables first.',
);
}

console.log({ domain, token });

setInterval(async () => {
const [err, res] = await checkIP(token, domain);
const d = new Date();
if (err) {
console.error(d, err);
} else {
if (res !== 'eq') {
console.log(d, res);
}
}
}, delay);
17 changes: 17 additions & 0 deletions src/useddns.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { assert } from 'https://deno.land/[email protected]/testing/asserts.ts';
import { getCurrentIP, getDNSIP } from './useddns.ts';

Deno.test('getCurrentIP', async () => {
const res = await getCurrentIP();
console.log(res);
assert(res.length > 0);
});

Deno.test('getDNSIP', async () => {
const res = await getDNSIP(
'www.google.com',
{ dns: '1.1.1.1' },
);
console.log(res);
assert(res.length > 0);
});
51 changes: 51 additions & 0 deletions src/useddns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { run } from 'https://deno.land/x/[email protected]/deno/run.ts';

export async function getIP(params: string): Promise<string> {
const { res } = await run(`dig ${params} +short -4`);
return res.replace(/(\r\n|\n|\r)/gm, '');
}

export function getCurrentIP(): Promise<string> {
return getIP('@ns1-1.akamaitech.net ANY whoami.akamai.net');
}

export function getDNSIP(
domain: string,
{ dns = '1.1.1.1' }: { dns?: string } = {},
): Promise<string> {
return getIP(`@${dns} A ${domain}`);
}

export async function checkIP(
token: string,
domain: string,
): Promise<[err: Error] | [err: null, res: string]> {
try {
const currentIP = await getCurrentIP();
const DNSIP = await getDNSIP(domain);
if (!currentIP || !DNSIP) {
throw new Error(
'Did not get IP: ' + JSON.stringify({ currentIP, DNSIP }),
);
}
if (currentIP !== DNSIP) {
console.log(JSON.stringify({ currentIP, DNSIP }));
const url = new URL('https://dyn.dns.he.net/nic/update');
url.searchParams.set('hostname', domain);
url.searchParams.set('password', token);
url.searchParams.set('myip', currentIP);
const res = await fetch(
url,
{ method: 'GET' },
);
console.log('res', res.status, res.headers, await res.text());
return [null, await res.text()];
}
return [null, 'eq'];
} catch (err) {
if (err instanceof Error) {
return [err];
}
return [new Error(`unknown ${err}`)];
}
}

0 comments on commit f9d42fc

Please sign in to comment.