181 lines
5.3 KiB
JavaScript
181 lines
5.3 KiB
JavaScript
/*global Vue*/
|
|
(function () {
|
|
'use strict';
|
|
var OAUTH3 = window.OAUTH3;
|
|
var oauth3 = OAUTH3.create({
|
|
host: window.location.host
|
|
, pathname: window.location.pathname.replace(/\/[^\/]*$/, '/')
|
|
});
|
|
var $ = function () { return document.querySelector.apply(document, arguments); };
|
|
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"
|
|
};
|
|
var vueData = {
|
|
claims: []
|
|
, domains: []
|
|
, newDomain: null
|
|
, newDomainWildcard: false
|
|
, newEmail: null
|
|
, hasAccount: false
|
|
, token: null
|
|
, site: { deviceDomain: document.location.hostname, deviceDomainA: dnsRecords[document.location.hostname] }
|
|
};
|
|
var app = new Vue({
|
|
el: '.v-app'
|
|
, data: vueData
|
|
, methods: {
|
|
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;
|
|
}
|
|
// we can just detect by text
|
|
if ('*.' === vueData.newDomain.slice(0, 2)) {
|
|
vueData.newDomain = vueData.newDomain.slice(2);
|
|
wildcard = true;
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
});
|
|
app = null;
|
|
|
|
function listStuff(data) {
|
|
//window.alert("TODO: show authorized devices, domains, and connectivity information");
|
|
vueData.hasAccount = true;
|
|
vueData.domains = data.domains;
|
|
vueData.claims = data.claims;
|
|
}
|
|
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: {
|
|
email: vueData.newEmail
|
|
}
|
|
}).then(function (resp) {
|
|
listStuff(resp);
|
|
});
|
|
} if (resp.data.accounts.length > 2) {
|
|
window.alert("Multiple accounts.");
|
|
} else {
|
|
window.alert("Bad response.");
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
function onChangeProvider(providerUri) {
|
|
// example https://oauth3.org
|
|
return oauth3.setIdentityProvider(providerUri);
|
|
}
|
|
|
|
// This opens up the login window for the specified provider
|
|
//
|
|
function onClickLogin(ev) {
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
|
|
var email = $('.js-auth-subject').value;
|
|
|
|
// TODO check subject for provider viability
|
|
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);
|
|
|
|
localStorage.setItem('session', JSON.stringify(session));
|
|
loadAccount(session);
|
|
});
|
|
|
|
});
|
|
|
|
}, function (err) {
|
|
console.error('Authentication Failed:');
|
|
console.log(err);
|
|
});
|
|
}
|
|
|
|
$('body form.js-auth-form').addEventListener('submit', onClickLogin);
|
|
onChangeProvider('oauth3.org');
|
|
if (session) {
|
|
vueData.token = session.access_token;
|
|
loadAccount(session);
|
|
}
|
|
}());
|