301 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			301 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.caddy/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.caddy/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.caddy/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*/) {
 | |
|       vm.admin.network.iface = 'oauth3-tunnel';
 | |
| 
 | |
|       return oauth3.request({
 | |
|         method: 'POST'
 | |
|       , url: 'https://' + vm.clientUri + '/api/com.daplie.caddy/tunnel'
 | |
|       /*
 | |
|       , data: {
 | |
|           method: 'GET'
 | |
|         , url: 'https://api.ipify.org?format=json'
 | |
|         }
 | |
|       */
 | |
|       });
 | |
|     };
 | |
| 
 | |
|     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);
 | |
| 
 | |
| });
 | |
| */
 |