forked from coolaj86/goldilocks.js
296 lines
9.3 KiB
JavaScript
296 lines
9.3 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');
|
|
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
|
|
|
|
return oauth3.authenticate().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;
|
|
});
|
|
};
|
|
|
|
oauth3.checkSession().then(function (session) {
|
|
console.log('hasSession?', session);
|
|
});
|
|
|
|
/*
|
|
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);
|
|
|
|
});
|
|
*/
|