cleanup
This commit is contained in:
		
							parent
							
								
									0a88802854
								
							
						
					
					
						commit
						0b93cdc2fa
					
				| @ -1,330 +0,0 @@ | |||||||
| (function () { |  | ||||||
|   'use strict'; |  | ||||||
| 
 |  | ||||||
|   console.log('[DAPLIE oauth3 directives.js]'); |  | ||||||
|   console.log(window.location); |  | ||||||
| 
 |  | ||||||
|   var iter = 0; |  | ||||||
| 
 |  | ||||||
|   function main() { |  | ||||||
| 
 |  | ||||||
|     var rpc = {}; |  | ||||||
|     //var myself = location.protocol + '//' + location.host + location.pathname;
 |  | ||||||
|     var incoming; |  | ||||||
|     var forwarding = {}; |  | ||||||
|     var err; |  | ||||||
|     var browserState; |  | ||||||
|     var browserCallback; |  | ||||||
|     var action; |  | ||||||
| 
 |  | ||||||
|     function parseParams() { |  | ||||||
|       var params = {}; |  | ||||||
| 
 |  | ||||||
|       function parseParamsString(str) { |  | ||||||
|         str.substr(1).split('&').filter(function (el) { return el; }).forEach(function (pair) { |  | ||||||
|           pair = pair.split('='); |  | ||||||
|           var key = decodeURIComponent(pair[0]); |  | ||||||
|           var val = decodeURIComponent(pair[1]); |  | ||||||
| 
 |  | ||||||
|           if (params[key]) { |  | ||||||
|             console.warn("overwriting key '" + key + "' '" + params[key] + "'"); |  | ||||||
|           } |  | ||||||
|           params[key] = val; |  | ||||||
|         }); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       parseParamsString(window.location.search); |  | ||||||
|       // handle cases where hash is treated like it's own href
 |  | ||||||
|       // TODO /#/?search=blah
 |  | ||||||
|       parseParamsString(window.location.hash); |  | ||||||
| 
 |  | ||||||
|       return params; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     function querystringify(params) { |  | ||||||
|       var arr = []; |  | ||||||
| 
 |  | ||||||
|       Object.keys(params).forEach(function (k) { |  | ||||||
|         arr.push(encodeURIComponent(k) + '=' + encodeURIComponent(params[k])); |  | ||||||
|       }); |  | ||||||
| 
 |  | ||||||
|       return arr.join('&'); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     function phoneAway(/*redirectURi, params*/) { |  | ||||||
|       // TODO test for ? / #
 |  | ||||||
|       window.location.href = incoming.redirect_uri + '#' + querystringify(forwarding); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     function lintAndSetRedirectable(browserState, params) { |  | ||||||
|       if (!params.redirect_uri) { |  | ||||||
|         window.alert('redirect_uri not defined'); |  | ||||||
|         err = new Error('redirect_uri not defined'); |  | ||||||
|         console.error(err.message); |  | ||||||
|         console.warn(err.stack); |  | ||||||
|         params.redirect_uri = document.referer; |  | ||||||
|         return false; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       if (!browserState) { |  | ||||||
|         forwarding.error = "E_NO_BROWSER_STATE"; |  | ||||||
|         forwarding.error_description = "you must specify a state parameter"; |  | ||||||
|         return false; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       localStorage.setItem('oauth3.states.' + browserState, JSON.stringify(params)); |  | ||||||
|       return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     function redirectCallback() { |  | ||||||
|       var redirect_uri = incoming.redirect_uri; |  | ||||||
|       forwarding.callback = browserState; |  | ||||||
|       forwarding.action = 'close'; |  | ||||||
| 
 |  | ||||||
|       var url = redirect_uri + '#' + querystringify(forwarding); |  | ||||||
| 
 |  | ||||||
|       console.log('[debug] redirect_uri + params:', url); |  | ||||||
|       window.location.href = url; |  | ||||||
|       setTimeout(function () { |  | ||||||
|         if (iter >= 3) { |  | ||||||
|           console.log("dancing way too much... stopping now"); |  | ||||||
|           return; |  | ||||||
|         } |  | ||||||
|         iter += 1; |  | ||||||
|         console.log("I'm dancing by myse-e-elf"); |  | ||||||
|         // in case I'm redirecting to myself
 |  | ||||||
|         main(); |  | ||||||
|       }, 0); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     rpc = {}; |  | ||||||
| 
 |  | ||||||
|     // Act as a provider and log the user out
 |  | ||||||
|     rpc.logout = function (browserState, incoming) { |  | ||||||
|       var url; |  | ||||||
|       if (!lintAndSetRedirectable(browserState, incoming)) { |  | ||||||
|         // TODO fail
 |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       localStorage.setItem('oauth3.states.' + browserState, JSON.stringify(incoming)); |  | ||||||
|       url = '/#/logout/' + browserState; |  | ||||||
| 
 |  | ||||||
|       // TODO specify specific account or all?
 |  | ||||||
|       window.location.href = url; |  | ||||||
|       setTimeout(function () { |  | ||||||
|         // in case I'm redirecting to myself
 |  | ||||||
|         main(); |  | ||||||
|       }, 0); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     // Act as a provider and inform the consumer the logout is complete
 |  | ||||||
|     rpc.logout_callback = function (browserState/*, incoming*/) { |  | ||||||
|       // TODO pass redirect_uri and state through here so we can avoid localStorage
 |  | ||||||
|       var forwarding = {}; |  | ||||||
|       var originalRequest; |  | ||||||
| 
 |  | ||||||
|       if (!browserState) { |  | ||||||
|         forwarding.error = "E_NO_BROWSER_STATE"; |  | ||||||
|         forwarding.error_description = "you must specify a state parameter"; |  | ||||||
|         if (incoming.redirect_uri) { |  | ||||||
|           phoneAway(incoming.redirect_uri, forwarding); |  | ||||||
|         } |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       originalRequest = JSON.parse(localStorage.getItem('oauth3.states.' + browserState)); |  | ||||||
|       forwarding.action = 'close'; |  | ||||||
|       forwarding.state = browserState; |  | ||||||
|       //phoneAway(originalRequest.redirect_uri, forwarding);
 |  | ||||||
|       window.location.href = originalRequest.redirect_uri + '#' + querystringify(forwarding); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     rpc.directives = function (browserState, incoming) { |  | ||||||
|       if (!lintAndSetRedirectable(browserState, incoming)) { |  | ||||||
|         phoneAway(); |  | ||||||
|         return; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       var updatedAt = new Date(localStorage.getItem('oauth3.directives.updated_at')).valueOf(); |  | ||||||
|       var fresh = (Date.now() - updatedAt) < (24 * 60 * 60 * 1000); |  | ||||||
|       var directives = localStorage.getItem('oauth3.directives'); |  | ||||||
|       var redirected = false; |  | ||||||
| 
 |  | ||||||
|       function redirectIf() { |  | ||||||
|         if (redirected) { |  | ||||||
|           return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         redirected = true; |  | ||||||
|         redirectCallback(); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       if (directives) { |  | ||||||
|         forwarding.directives = directives; |  | ||||||
|         redirectIf(); |  | ||||||
|         if (fresh) { |  | ||||||
|           return; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       var req = new XMLHttpRequest(); |  | ||||||
|       req.open('GET', '.well-known/oauth3.json', true); |  | ||||||
|       req.addEventListener('readystatechange', function () { |  | ||||||
|         if (4 !== req.readyState) { |  | ||||||
|           return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (200 !== req.status) { |  | ||||||
|           forwarding.error = "E_STATUS_" + req.status; |  | ||||||
|           forwarding.error_description = "expected 200 OK json or text response for oauth3.json but got '" + req.status + "'"; |  | ||||||
|           redirectIf(); |  | ||||||
|           return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         try { |  | ||||||
|           directives = btoa(JSON.stringify(JSON.parse(req.responseText))); |  | ||||||
|           forwarding.directives = directives; |  | ||||||
|           forwarding.callback = browserState; |  | ||||||
|           localStorage.setItem('oauth3.directives', directives); |  | ||||||
|           localStorage.setItem('oauth3.directives.updated_at', new Date().toISOString()); |  | ||||||
|         } catch(e) { |  | ||||||
|           forwarding.error = "E_PARSE_JSON"; |  | ||||||
|           forwarding.error_description = e.message; |  | ||||||
|           console.error(forwarding.error); |  | ||||||
|           console.error(forwarding.error_description); |  | ||||||
|           console.error(req.responseText); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         redirectIf(); |  | ||||||
|       }); |  | ||||||
|       req.send(); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     // the provider is contacting me
 |  | ||||||
|     rpc.close = function (browserState, incoming) { |  | ||||||
|       incoming.callback = browserState; |  | ||||||
|       catchAll(); |  | ||||||
|     }; |  | ||||||
|     // the provider is contacting me
 |  | ||||||
|     rpc.redirect = function (/*browserState, incoming*/) { |  | ||||||
|       catchAll(); |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     function catchAll() { |  | ||||||
|       function phoneHome() { |  | ||||||
|         if (browserCallback === 'completeLogin') { |  | ||||||
|           // Deprecated
 |  | ||||||
|           console.log('[deprecated] callback completeLogin'); |  | ||||||
|           (window.opener||window.parent).completeLogin(null, null, incoming); |  | ||||||
|         } else { |  | ||||||
|           console.log('[DEBUG] I would be closed by my parent now'); |  | ||||||
|           console.log('__oauth3_' + browserCallback); |  | ||||||
|           console.log(window.opener && window.opener['__oauth3_' + browserCallback]); |  | ||||||
|           console.log(window.parent && window.parent['__oauth3_' + browserCallback]); |  | ||||||
|           console.log(incoming); |  | ||||||
|           (window.opener||window.parent)['__oauth3_' + browserCallback](incoming); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       if (!(incoming.browser_state || incoming.state)) { |  | ||||||
|         window.alert("callback URLs should include 'browser_state' (authorization code)" |  | ||||||
|           + " or 'state' (implicit grant))"); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       setTimeout(function () { |  | ||||||
|         // opener is for popup window, new tab
 |  | ||||||
|         // parent is for iframe
 |  | ||||||
|         phoneHome(); |  | ||||||
|       }, 10); |  | ||||||
| 
 |  | ||||||
|       // iOS Webview (namely Chrome) workaround
 |  | ||||||
|       setTimeout(function () { |  | ||||||
|         console.log('I would close now'); |  | ||||||
|         // XXX OAUTH3 DEBUG FRAME XXX // make this easy to find
 |  | ||||||
|         window.open('', '_self', ''); |  | ||||||
|         window.close(); |  | ||||||
|       }, 50); |  | ||||||
| 
 |  | ||||||
|       setTimeout(function () { |  | ||||||
|         var i; |  | ||||||
|         var len = localStorage.length; |  | ||||||
|         var key; |  | ||||||
|         var json; |  | ||||||
|         var fresh; |  | ||||||
| 
 |  | ||||||
|         for (i = 0; i < len; i += 1) { |  | ||||||
|           key = localStorage.key(i); |  | ||||||
|           // TODO check updatedAt
 |  | ||||||
|           if (/^oauth3\./.test(key)) { |  | ||||||
|             try { |  | ||||||
|               json = localStorage.getItem(key); |  | ||||||
|               if (json) { |  | ||||||
|                 json = JSON.parse(json); |  | ||||||
|               } |  | ||||||
|             } catch (e) { |  | ||||||
|               // ignore
 |  | ||||||
|               json = null; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             fresh = json && (Date.now() - json.updatedAt < (5 * 60 * 1000)); |  | ||||||
| 
 |  | ||||||
|             if (!fresh) { |  | ||||||
|               localStorage.removeItem(key); |  | ||||||
|             } |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|         forwarding.updatedAt = Date.now(); |  | ||||||
|         localStorage.setItem('oauth3.' + (forwarding.browser_state || forwarding.state), JSON.stringify(forwarding)); |  | ||||||
|       }, 0); |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     function parseAction(params) { |  | ||||||
|       if (params.action) { |  | ||||||
|         return params.action; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       if (params.close) { |  | ||||||
|         return 'close'; |  | ||||||
|       } |  | ||||||
|       if (params.logout_callback) { |  | ||||||
|         return 'logout_callback'; |  | ||||||
|       } |  | ||||||
|       if (params.logout) { |  | ||||||
|         return 'logout'; |  | ||||||
|       } |  | ||||||
|       if (params.callback) { |  | ||||||
|         return 'close'; |  | ||||||
|       } |  | ||||||
|       if (params.directives) { |  | ||||||
|         return 'directives'; |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       return 'redirect'; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     incoming = parseParams(); |  | ||||||
|     browserState = incoming.browser_state || incoming.state; |  | ||||||
|     action = parseAction(incoming); |  | ||||||
|     forwarding.url = window.location.href; |  | ||||||
|     forwarding.browser_state = browserState; |  | ||||||
|     forwarding.state = browserState; |  | ||||||
| 
 |  | ||||||
|     if (!incoming.provider_uri) { |  | ||||||
|       browserCallback = incoming.callback || browserState; |  | ||||||
|     } else { |  | ||||||
|       // deprecated
 |  | ||||||
|       browserCallback = 'completeLogin'; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     console.log('[debug]', action, incoming); |  | ||||||
| 
 |  | ||||||
|     if (rpc[action]) { |  | ||||||
|       rpc[action](browserState, incoming); |  | ||||||
|     } else { |  | ||||||
|       window.alert('unsupported action'); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   main(); |  | ||||||
| }()); |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user