telebit-relay.js/lib/extensions/admin/js/account.js

216 lines
6.3 KiB
JavaScript
Raw Permalink Normal View History

2018-08-19 07:33:03 +00:00
/*global Vue*/
2018-08-10 07:44:42 +00:00
(function () {
'use strict';
var OAUTH3 = window.OAUTH3;
var oauth3 = OAUTH3.create({
host: window.location.host
, pathname: window.location.pathname.replace(/\/[^\/]*$/, '/')
});
2018-08-20 17:42:59 +00:00
//var $ = function () { return document.querySelector.apply(document, arguments); };
2018-08-19 07:33:03 +00:00
var sessionStr = localStorage.getItem('session');
var session;
if (sessionStr) {
try {
session = JSON.parse(sessionStr);
} catch(e) {
// ignore
}
}
var dnsRecords = {
"telebit.ppl.family": "178.128.3.196"
, "telebit.cloud": "46.101.97.218"
};
2018-08-10 08:48:06 +00:00
var vueData = {
2018-08-19 07:33:03 +00:00
claims: []
, domains: []
2018-08-20 19:38:58 +00:00
, devices: []
2018-08-10 08:48:06 +00:00
, newDomain: null
2018-08-19 07:33:03 +00:00
, newDomainWildcard: false
2018-08-10 08:48:06 +00:00
, newEmail: null
, hasAccount: false
, token: null
2018-08-20 17:42:59 +00:00
, spinner: false
, site: { deviceDomain: document.location.hostname, deviceDomainA: dnsRecords[document.location.hostname] }
2018-08-10 08:48:06 +00:00
};
2018-08-20 17:42:59 +00:00
var vueMethods = {
challengeDns: function () {
// we could do a checkbox
var wildcard = vueData.newDomainWildcard || false;
if (!/(\*\.)?[a-z0-9][a-z0-9\.\-_]\.[a-z0-9]{2,}/.test(vueData.newDomain)) {
window.alert("invalid domain name '" + vueData.newDomain + "'");
return;
2018-08-10 08:48:06 +00:00
}
2018-08-20 17:42:59 +00:00
// we can just detect by text
if ('*.' === vueData.newDomain.slice(0, 2)) {
vueData.newDomain = vueData.newDomain.slice(2);
wildcard = true;
2018-08-10 08:48:06 +00:00
}
2018-08-20 17:42:59 +00:00
return oauth3.request({
url: 'https://api.' + location.hostname + '/api/telebit.cloud/account/authorizations/new'
, method: 'POST'
, session: session
, data: { type: 'dns', value: vueData.newDomain, wildcard: wildcard }
}).then(function (resp) {
vueData.claims.unshift(resp.data.claim);
});
}
, checkDns: function (claim) {
return oauth3.request({
url: 'https://api.' + location.hostname + '/api/telebit.cloud/account/authorizations/new/:value/:challenge'
.replace(/:value/g, claim.value)
.replace(/:challenge/g, claim.challenge)
, method: 'POST'
, session: session
});
}
, challengeEmail: function () {
console.log("A new (Email) challenger!", vueData);
}
2018-08-20 20:12:28 +00:00
, pushDomain: function (dev) {
// TODO do some local validation too
console.log('pushDomain', dev);
vueData.spinner = true;
return oauth3.request({
url: 'https://api.' + location.hostname + '/api/telebit.cloud/devices/:dev/:name'
.replace(/:dev/g, dev.socketId)
.replace(/:name/g, dev.newDomain)
, method: 'POST'
, session: session
}).catch(function (err) {
console.error(err);
window.alert(err.toString());
}).then(function () {
dev.newDomain = '';
vueData.spinner = false;
});
}
2018-08-20 17:42:59 +00:00
, login: function () {
var email = vueData.newEmail;
vueMethods.logout();
onClickLogin(email);
2018-08-10 08:48:06 +00:00
}
2018-08-20 17:42:59 +00:00
, logout: function () {
sessionStorage.clear();
vueData.hasAccount = false;
// TODO OAUTH3._logoutHelper(directives, opts)
}
};
var app = new Vue({
el: '.v-app'
, data: vueData
, methods: vueMethods
2018-08-10 08:48:06 +00:00
});
2018-08-19 07:33:03 +00:00
app = null;
2018-08-10 08:48:06 +00:00
function listStuff(data) {
//window.alert("TODO: show authorized devices, domains, and connectivity information");
vueData.hasAccount = true;
vueData.domains = data.domains;
2018-08-20 19:38:58 +00:00
vueData.devices = data.devices;
2018-08-19 07:33:03 +00:00
vueData.claims = data.claims;
2018-08-10 08:48:06 +00:00
}
function loadAccount(session) {
return oauth3.request({
url: 'https://api.' + location.hostname + '/api/telebit.cloud/account'
, session: session
}).then(function (resp) {
console.info("Telebit Account:");
console.log(resp.data);
if (resp.data && resp.data.domains) {
listStuff(resp.data);
return;
}
if (1 === resp.data.accounts.length) {
listStuff(resp);
} else if (0 === resp.data.accounts.length) {
return oauth3.request({
url: 'https://api.' + location.hostname + 'api/telebit.cloud/account'
, method: 'POST'
, session: session
, body: {
2018-08-19 07:33:03 +00:00
email: vueData.newEmail
2018-08-10 08:48:06 +00:00
}
}).then(function (resp) {
listStuff(resp);
});
} if (resp.data.accounts.length > 2) {
window.alert("Multiple accounts.");
} else {
window.alert("Bad response.");
}
});
}
2018-08-10 07:44:42 +00:00
function onChangeProvider(providerUri) {
// example https://oauth3.org
return oauth3.setIdentityProvider(providerUri);
}
// This opens up the login window for the specified provider
//
2018-08-20 17:42:59 +00:00
function onClickLogin(email) {
2018-08-10 07:44:42 +00:00
// TODO check subject for provider viability
2018-08-20 17:42:59 +00:00
vueData.spinner = true;
2018-08-10 07:44:42 +00:00
return oauth3.authenticate({
subject: email
, scope: 'email@oauth3.org'
}).then(function (session) {
console.info('Authentication was Successful:');
console.log(session);
// You can use the PPID (or preferably a hash of it) as the login for your app
// (it securely functions as both username and password which is known only by your app)
// If you use a hash of it as an ID, you can also use the PPID itself as a decryption key
//
console.info('Secure PPID (aka subject):', session.token.sub);
return oauth3.request({
url: 'https://api.oauth3.org/api/issuer@oauth3.org/jwks/:sub/:kid.json'
.replace(/:sub/g, session.token.sub)
.replace(/:kid/g, session.token.iss)
, session: session
}).then(function (resp) {
console.info("Public Key:");
console.log(resp.data);
return oauth3.request({
url: 'https://api.oauth3.org/api/issuer@oauth3.org/acl/profile'
, session: session
}).then(function (resp) {
console.info("Inspect Token:");
console.log(resp.data);
2018-08-10 08:48:06 +00:00
localStorage.setItem('session', JSON.stringify(session));
2018-08-19 07:33:03 +00:00
loadAccount(session);
2018-08-10 07:44:42 +00:00
});
});
}, function (err) {
console.error('Authentication Failed:');
console.log(err);
2018-08-20 17:42:59 +00:00
}).then(function () {
vueData.spinner = false;
2018-08-10 07:44:42 +00:00
});
}
2018-08-20 17:42:59 +00:00
//$('body form.js-auth-form').addEventListener('submit', function onClickLoginHelper(ev) {
// ev.preventDefault();
// ev.stopPropagation();
// var email = $('.js-auth-subject').value;
// onClickLogin(email);
//});
2018-08-10 07:44:42 +00:00
onChangeProvider('oauth3.org');
2018-08-10 08:48:06 +00:00
if (session) {
2018-08-19 07:33:03 +00:00
vueData.token = session.access_token;
2018-08-10 08:48:06 +00:00
loadAccount(session);
}
2018-08-10 07:44:42 +00:00
}());