| 
									
										
										
										
											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
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-19 16:25:36 +00:00
										 |  |  |   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 | 
					
						
							| 
									
										
										
										
											2018-08-19 16:25:36 +00:00
										 |  |  |   , 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
										 |  |  | }()); |