goldilocks.js/admin/public/js/app.js

302 line
9.4 KiB
JavaScript

angular.module('com.daplie.cloud', [ 'org.oauth3' ])
.service('oauth3', [ 'Oauth3', function (Oauth3) {
// for security this app should not store the refresh token
// (the localhost.* domains should never store them)
Oauth3.hooks.session._store = {};
Oauth3.hooks.session._get = function (providerUri) {
return Oauth3.PromiseA.resolve(Oauth3.hooks.session._store[providerUri]);
};
Oauth3.hooks.session._set = function (providerUri, session) {
Oauth3.hooks.session._store[providerUri] = session;
return Oauth3.PromiseA.resolve(session);
};
var auth = Oauth3.create();
auth.setProvider('oauth3.org').then(function () {
auth.checkSession().then(function (session) {
console.log('hasSession?', session);
});
});
window.oauth3 = auth; // debug
return auth;
} ])
.controller('LoginController', [ '$scope', '$timeout', 'oauth3', function ($scope, $timeout, oauth3) {
var vm = this;
var OAUTH3 = window.OAUTH3;
vm.admin = { network: { iface: null, ipv4: null, ipv6: null } };
vm.admin.ipify = 'https://api.ipify.org?format=json';
vm.clientUri = OAUTH3.clientUri(window.location);
vm.setSimple = function () {
vm.advanced = false;
vm.providerUri = vm.providerUri || 'oauth3.org';
};
vm.setAdvanced = function () {
vm.advanced = true;
vm.myProviderUri = vm.providerUri;
};
vm.checkProviderUri = function (myProviderUri) {
$timeout.cancel(vm.checkProviderTimeout);
vm.providerUri = null;
vm.checkProviderTimeout = $timeout(function () {
//var providerUri = vm.providerUri;
return oauth3.setProvider(myProviderUri).then(function (directives) {
console.log('directives', directives);
vm.providerUri = myProviderUri;
}, function (err) {
console.error('failed provider lookup', err);
vm.checkProviderTimeout = null;
});
}, 250);
};
vm.sortDnsRecords = function (a, b) {
if (a.sld !== b.sld) {
return a.sld > b.sld ? 1 : -1;
}
if (a.tld !== b.tld) {
return a.tld > b.tld ? 1 : -1;
}
// TODO normalize
a.sub = a.sub || '';
b.sub = b.sub || '';
if (a.sub !== b.sub) {
if (!a.sub) {
return -1;
}
if (!b.sub) {
return 1;
}
return a.sub > b.sub ? 1 : -1;
}
if (a.domain !== b.domain) {
if (!a.domain) {
return 1;
}
if (!b.domain) {
return -1;
}
}
};
vm.viewDomains = function (config, domains, dns) {
vm.dns = dns.slice(0);
vm.domains = domains.slice(0);
vm.domains.sort(vm.sortDnsRecords);
vm.dns = vm.dns.filter(function (record) {
if (-1 === [ 'A', 'AAAA', 'ANAME' ].indexOf(record.type)) {
return false;
}
if (record.device !== config.device.hostname) {
return false;
}
return true;
});
vm.dns.forEach(function (r) {
vm.domains.forEach(function (d) {
if (r.zone === d.domain) {
r.sub = r.name.substr(0, r.name.length - (d.domain.length + 1));
r.tld = d.tld;
r.sld = d.sld;
}
});
});
vm.dns = vm.dns.concat(vm.domains);
vm.dns.sort(vm.sortDnsRecords);
vm.dns.forEach(function (r) {
if (r.domain) {
return;
}
r.devices = r.devices || [ r.device ];
dns.forEach(function (r2) {
if (r.name !== r2.name) {
return;
}
if (-1 !== r.devices.indexOf(r2.device)) {
return;
}
r.devices.push(r2.device);
});
});
console.log('vm.dns');
console.log(vm.dns);
/*
vm.domains.forEach(function (d) {
d.devices = [];
dns.forEach(function (r) {
// 0 === r.name.split('').reverse().join('').indexOf(d.domain.split('').reverse().join(''))
if (r.zone === d.domain) {
d.devices.push({
name: r.device
});
}
});
});
*/
};
vm.authenticate = function () {
// TODO authorization redirect /api/org.oauth3.consumer/authorization_redirect/:provider_uri
var opts = {
type: 'popup'
, scope: 'domains,dns'
// , debug: true
};
return oauth3.authenticate(opts).then(function (session) {
console.info("Authorized Session", session);
return oauth3.api('domains.list').then(function (domains) {
console.info("domains owned", domains);
return oauth3.api('dns.list').then(function (dns) {
console.info("dns records", dns);
return OAUTH3.request({
method: 'POST'
, url: 'https://' + vm.clientUri + '/api/com.daplie.goldilocks/init'
, session: session
, data: {
access_token: session.access_token
, refresh_token: session.refresh_token
, expires_in: session.expires_in
, scope: session.scope
, provider_uri: OAUTH3.uri.normalize(session.provider_uri)
, client_uri: vm.clientUri
, domains: domains.map(function (d) {
return {
id: d.id
, sub: d.sub
, sld: d.sld
, tld: d.tld
};
})
, jwk: null // TODO publish public key
}
}).then(function (resp) {
// TODO resp should contain a token
console.info('Initialized Goldilocks', resp);
return OAUTH3.request({
method: 'GET'
, url: 'https://' + vm.clientUri + '/api/com.daplie.goldilocks/config'
, session: session
}).then(function (configResp) {
console.log('config', configResp.data);
vm.config = configResp.data;
vm.config.addresses.forEach(function (addr) {
if (/unicast/.test(addr.range) || /internet/i.test(addr.range)) {
// TODO
// there could be more than one iface (ipv4 on one and ipv6 on the other)
// there could also be more than one valid public ip
if ("IPv4" === addr.family) {
vm.admin.network.iface = addr.iface;
vm.admin.network.ipv4 = addr.address;
}
else if ("IPv6" === addr.family) {
// IPv6 gives valid internet address even when behind a firewall
// IPv6 requires a loopback test
// TODO always do the loopback / firewall test anyway
vm.admin.network.ipv6 = addr.address;
}
}
});
vm.admin.servername = vm.config.device.hostname;
//vm.config.ifaces
//vm.config.addresses = [];
vm.viewDomains(vm.config, domains, dns);
if (vm.admin.network.iface) {
return resp;
}
// TODO try UPnP IGD / NAT-PMP / DNS-SD / PCP (ipv6) here
// TODO two requests - one to {{ipv4.ipify.org}}, the other to {{ipv6.ipify.org}}
vm.admin.network.iface = 'gateway';
return OAUTH3.request({
method: 'POST'
, url: 'https://' + vm.clientUri + '/api/com.daplie.goldilocks/request'
, session: session
, data: {
method: 'GET'
, url: 'https://api.ipify.org?format=json'
}
}).then(function (ipResp) {
console.log('ip-response', ipResp);
vm.admin.network.ipv4 = ipResp.data.body.ipv4 || ipResp.data.body.ip;
vm.admin.network.ipv6 = ipResp.data.body.ipv6;
return resp;
});
});
}, function (err) {
console.error(err);
window.alert("Initialization failed:" + err.message);
});
});
});
}, function (err) {
console.error(err);
window.alert("Authentication failed:" + err.message);
});
};
vm.enableTunnel = function (/*opts*/) {
return oauth3.request({
method: 'POST'
, url: 'https://' + vm.clientUri + '/api/com.daplie.goldilocks/tunnel'
}).then(function (result) {
// vm.admin.network.iface = 'oauth3-tunnel';
return result;
});
};
/*
console.log('OAUTH3.PromiseA', OAUTH3.PromiseA);
return oauth3.setProvider('oauth3.org').then(function () {
return oauth3.authenticate({ windowType: 'background' }).then(function () {
console.log('HELLO!!');
//vm.authnUpdated = Date.now();
vm.hasSession = true;
}, function () {
console.log('GOODBYE!!');
//vm.authnUpdated = Date.now();
vm.hasSession = false;
$timeout(function () {
console.log('GOODBYE!!');
vm.hello = 'Nope!';
}, 1);
});
});
//*/
}]);
/*
$(function () {
'use strict';
var ui = {
function login() {
}
};
var auth = window.OAUTH3.create();
// TODO put explicit in dns record
// TODO CCA record
auth.setProvider('oauth3.org');
$('body').on('click', '.js-login', login);
});
*/