commit 1b193248ed097fac370d01858856d061d92e6b9d Author: adb Date: Tue Mar 30 23:40:33 2021 +0200 add project files diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..3673603 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,31 @@ +module.exports = { + "env": { + "browser": true, + "es6": true + }, + "extends": [ + "eslint:recommended", + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "indent": [ + "warn", + 2 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "warn", + "single" + ] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cffcb3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.json \ No newline at end of file diff --git a/DynDnsBot.js b/DynDnsBot.js new file mode 100644 index 0000000..658a23f --- /dev/null +++ b/DynDnsBot.js @@ -0,0 +1,31 @@ +import {OvhApi} from './OvhApi.js'; +import rest from 'superagent'; + +export class DynDnsBot{ + constructor({config}){ + this.config = config; + this.dns = new OvhApi({credentials: config.ovhCredentials}); + this.lastIp = null; + } + + async update() { + let newIp = await this.getIp(); + if (newIp === this.lastIp) return; + this.lastIp = newIp; + this.config.records.forEach(record => { + record.target = newIp; + this.dns.updateRecord(record); + }); + } + setInterval(seconds = this.config.updateInterval, random = this.config.randomInterval){ + this.interval = setInterval(random + ?setTimeout(this.update, Math.random()*seconds*1000) + :this.update, + seconds*1000); + } + async getIp(){ + return await rest.get(this.config.ipApi).then(newIp => { + return newIp; + }).catch(console.error); + } +} \ No newline at end of file diff --git a/OvhApi.js b/OvhApi.js new file mode 100644 index 0000000..c190f97 --- /dev/null +++ b/OvhApi.js @@ -0,0 +1,55 @@ +import rest from 'superagent'; + +export class OvhApi{ + async constructor({credentials}){ + this.credentials = credentials; + this.baseUrl = credentials.apiUrl; + this.apiToken = await this.getToken({applicationKey: credentials.applicationKey}); + } + + async sendRequest({ + path, + obj={}, + method=rest=>rest.get, + header={accept: 'json'} + }){ + let request = method(rest)(`${this.baseUrl}${path}`); + await Object.keys(header).forEach(key => request.set(key, header[key])); + return await request.send(obj).then(res => { + return JSON.parse(res.text); + }).catch(err => { + console.log(err); + return false; + }); + } + + async getToken({applicationKey}){ + return await this.sendRequest({ + path: '/auth/credential', + method: rest=>rest.post, + header: { + 'X-Ovh-Application': applicationKey, + 'Content-type': 'application/json' + }, + obj: { + accessRules: [ + {method: 'GET', path: '/domain/zone/*'}, + {method: 'POST', path: '/domain/zone/*'}, + {method: 'PUT', path: '/domain/zone/*'} + ] + } + }); + } + + async updateRecord({domain, subDomain, recordId, target, ttl = 3600}){ + return await this.sendRequest({ + path: `/domain/zone/${domain}/record/${recordId}`, + method: rest=>rest.put, + obj: { + subDomain, + target, + ttl + } + }); + } +} \ No newline at end of file diff --git a/example.config.json b/example.config.json new file mode 100644 index 0000000..92a5a7a --- /dev/null +++ b/example.config.json @@ -0,0 +1,15 @@ +{ + "ipApi": "https://api.ipify.org/", + "updateInterval": 300, + "randomInterval": true, + "records": [{ + "domain": "foo.bar", + "subDomain": "foo.foo.bar", + "recordId": 0, + "ttl": 300 + }], + "ovhCredentials": { + "applicationKey": "", + "apiUrl": "https://ca.api.ovh.com/1.0" + } +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..1cbcd84 --- /dev/null +++ b/index.js @@ -0,0 +1,5 @@ +import {DynDnsBot} from './DynDnsBot.js'; +import {loadData} from './jsonDataStore.js'; + +let bot = new DynDnsBot({config: loadData('config.json')}); +bot.setInterval(); \ No newline at end of file diff --git a/jsonDataStore.js b/jsonDataStore.js new file mode 100644 index 0000000..0f313f0 --- /dev/null +++ b/jsonDataStore.js @@ -0,0 +1,25 @@ +import fs from "fs"; + +export function storeData(data, path) { + try { + fs.writeFileSync(path, JSON.stringify(data)); + } catch (err) { + console.error(err); + } +} +export function loadData(path) { + try { + return JSON.parse(fs.readFileSync(path, 'utf8')) + } catch (err) { + console.error(err) + return false + } +} +export function getStat(path) { + try { + return fs.existsSync(path) === true; + } catch(err) { + console.error(err) + return false; + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..a64519b --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "ovh-api-dyndns", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "adb", + "license": "", + "dependencies": { + "superagent": "^6.1.0" + }, + "devDependencies": { + "eslint": "^6.7.2" + } +}