goldilocks.js/lib/ddns.js

117 lines
3.4 KiB
JavaScript
Raw Normal View History

2016-10-17 23:40:55 +00:00
'use strict';
2017-09-14 21:26:19 +00:00
module.exports.create = function (deps, conf) {
var PromiseA = deps.PromiseA;
var request = PromiseA.promisify(require('request'));
var OAUTH3 = require('../packages/assets/org.oauth3');
require('../packages/assets/org.oauth3/oauth3.dns.js');
2016-10-17 23:40:55 +00:00
2017-09-14 21:26:19 +00:00
function dnsType(addr) {
if (/^\d+\.\d+\.\d+\.\d+$/.test(addr)) {
return 'A';
}
if (-1 !== addr.indexOf(':') && /^[a-f:\.\d]+$/i.test(addr)) {
return 'AAAA';
}
}
2016-10-17 23:40:55 +00:00
2017-09-14 21:26:19 +00:00
function setDeviceAddress(addr) {
return deps.storage.owners.all().then(function (sessions) {
return sessions.filter(function (sess) {
return sess.token.scp.indexOf('dns') >= 0;
})[0];
}).then(function (session) {
if (!session) {
return PromiseA.reject(new Error('no sessions with DNS grants'));
}
2016-10-17 23:40:55 +00:00
2017-09-14 21:26:19 +00:00
return OAUTH3.discover(session.aud).then(function (directives) {
return request({
url: 'https://'+directives.api+'/api/org.oauth3.dns/acl/devices/' + conf.device.hostname
, method: 'POST'
, headers: {
'Authorization': 'Bearer ' + session.refresh_token
, 'Accept': 'application/json; charset=utf-8'
2016-10-17 23:40:55 +00:00
}
2017-09-14 21:26:19 +00:00
, json: {
addresses: [
{ value: addr, type: dnsType(addr) }
]
2016-10-17 23:40:55 +00:00
}
});
});
});
2017-09-14 21:26:19 +00:00
}
2016-10-17 23:40:55 +00:00
2017-09-14 21:26:19 +00:00
function getDeviceAddresses() {
return deps.storage.owners.all().then(function (sessions) {
return sessions.filter(function (sess) {
return sess.token.scp.indexOf('dns') >= 0;
})[0];
}).then(function (session) {
if (!session) {
return PromiseA.reject(new Error('no sessions with DNS grants'));
}
2016-10-17 23:40:55 +00:00
2017-09-14 21:26:19 +00:00
return OAUTH3.discover(session.aud).then(function (directives) {
return request({
url: 'https://'+directives.api+'/api/org.oauth3.dns/acl/devices'
, method: 'GET'
, headers: {
'Authorization': 'Bearer ' + session.refresh_token
, 'Accept': 'application/json; charset=utf-8'
}
, json: true
});
}).then(function (result) {
if (!result.body) {
return PromiseA.reject(new Error('No response body in request for device addresses'));
2016-10-17 23:40:55 +00:00
}
2017-09-14 21:26:19 +00:00
if (result.body.error) {
var err = new Error(result.body.error.message);
return PromiseA.reject(Object.assign(err, result.body.error));
}
return result.body.devices.filter(function (dev) {
return dev.name === conf.device.hostname;
})[0];
}).then(function (dev) {
return (dev || {}).addresses || [];
2016-10-17 23:40:55 +00:00
});
});
2017-09-14 21:26:19 +00:00
}
var publicAddress;
function recheckPubAddr() {
if (!conf.ddns.enabled) {
return;
}
deps.storage.owners.all().then(function (sessions) {
return sessions.filter(function (sess) {
return sess.token.scp.indexOf('dns') >= 0;
})[0];
}).then(function (session) {
if (!session) {
return;
}
2016-10-17 23:40:55 +00:00
2017-09-14 21:26:19 +00:00
OAUTH3.discover(session.aud).then(function (directives) {
return deps.loopback.checkPublicAddr(directives.api);
}).then(function (addr) {
if (publicAddress !== addr) {
publicAddress = addr;
setDeviceAddress(addr);
2016-10-17 23:40:55 +00:00
}
});
});
2017-09-14 21:26:19 +00:00
}
2016-10-17 23:40:55 +00:00
2017-09-14 21:26:19 +00:00
setInterval(recheckPubAddr, 5*60*1000);
2016-10-17 23:40:55 +00:00
2017-09-14 21:26:19 +00:00
return {
setDeviceAddress: setDeviceAddress
, getDeviceAddresses: getDeviceAddresses
, recheckPubAddr: recheckPubAddr
2016-10-17 23:40:55 +00:00
};
2017-09-14 21:26:19 +00:00
};