WIP frameRequest refactor (iframe, window.open)
This commit is contained in:
		
							parent
							
								
									458649d073
								
							
						
					
					
						commit
						d6e29cd0fa
					
				| @ -251,7 +251,7 @@ | |||||||
|       ).then(function (params) { |       ).then(function (params) { | ||||||
|         // discWin.child.close()
 |         // discWin.child.close()
 | ||||||
|         // TODO params should have response_type indicating json, binary, etc
 |         // TODO params should have response_type indicating json, binary, etc
 | ||||||
|         var directives = JSON.parse(OAUTH3.utils.atob(OAUTH3.utils.urlSafeBase64ToBase64(params.result || params.directives))); |         var directives = JSON.parse(OAUTH3.utils.atob(OAUTH3.utils._urlSafeBase64ToBase64(params.result || params.directives))); | ||||||
|         return OAUTH3.hooks.directives.set(providerUri, directives); |         return OAUTH3.hooks.directives.set(providerUri, directives); | ||||||
|       }); |       }); | ||||||
|     } |     } | ||||||
| @ -310,7 +310,6 @@ | |||||||
|             xhr = new XMLHttpRequest(); |             xhr = new XMLHttpRequest(); | ||||||
|           } |           } | ||||||
|           xhr.onreadystatechange = function () { |           xhr.onreadystatechange = function () { | ||||||
|             console.error('state change'); |  | ||||||
|             var data; |             var data; | ||||||
|             if (xhr.readyState !== XMLHttpRequest.DONE) { |             if (xhr.readyState !== XMLHttpRequest.DONE) { | ||||||
|               // nothing to do here
 |               // nothing to do here
 | ||||||
| @ -365,7 +364,10 @@ | |||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         // TODO ability to reuse iframe instead of closing
 |         // TODO ability to reuse iframe instead of closing
 | ||||||
|         return OAUTH3._browser._iframe.insert(discObj.url, discObj.state, opts).then(function (params) { |         opts._windowType = opts.windowType; | ||||||
|  |         opts.windowType = opts.windowType || 'background'; | ||||||
|  |         return OAUTH3._browser.frameRequest(discObj.url, discObj.state, opts).then(function (params) { | ||||||
|  |           opts.windowType = opts._windowType; | ||||||
|           OAUTH3._browser.closeFrame(discObj.state, { debug: opts.debug || params.debug }); |           OAUTH3._browser.closeFrame(discObj.state, { debug: opts.debug || params.debug }); | ||||||
|           if (params.error) { |           if (params.error) { | ||||||
|             return OAUTH3.utils._formatError(providerUri, params.error); |             return OAUTH3.utils._formatError(providerUri, params.error); | ||||||
| @ -378,47 +380,67 @@ | |||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|     , frameRequest: function (url, state, opts) { |     , frameRequest: function (url, state, opts) { | ||||||
|  |         opts = opts || {}; | ||||||
|         var previousFrame = OAUTH3._browser._frames[state]; |         var previousFrame = OAUTH3._browser._frames[state]; | ||||||
| 
 | 
 | ||||||
|         if (!opts.windowType) { |         var windowType = opts.windowType; | ||||||
|           opts.windowType = 'popup'; |         if (!windowType) { | ||||||
|  |           windowType = 'popup'; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         opts = opts || {}; |         var timeout = opts.timeout; | ||||||
|         if (opts.debug) { |         if (opts.debug) { | ||||||
|           opts.timeout = opts.timeout || 15 * 60 * 1000; |           timeout = timeout || 3 * 60 * 1000; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |           timeout = timeout || ('background' === windowType ? 15 * 1000 : 3 * 60 * 1000); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return new OAUTH3.PromiseA(function (resolve, reject) { |         return new OAUTH3.PromiseA(function (resolve, reject) { | ||||||
|  |           // TODO periodically garbage collect expired handlers from window object
 | ||||||
|           var tok; |           var tok; | ||||||
| 
 | 
 | ||||||
|           function cleanup() { |           function cleanup() { | ||||||
|             delete window['--oauth3-callback-' + state]; |             delete window['--oauth3-callback-' + state]; | ||||||
|             clearTimeout(tok); |             clearTimeout(tok); | ||||||
|             tok = null; |             tok = null; | ||||||
|  |             // the actual close is done later (by the caller) so that the window/frame
 | ||||||
|  |             // can be reused or self-closes synchronously itself / by parent
 | ||||||
|  |             // (probably won't ever happen, but that's a negotiable implementation detail)
 | ||||||
|           } |           } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |           console.log('[oauth3.implicit.js] callbackName', '--oauth3-callback-' + state); | ||||||
|           window['--oauth3-callback-' + state] = function (params) { |           window['--oauth3-callback-' + state] = function (params) { | ||||||
|             resolve(params); |             resolve(params); | ||||||
|             cleanup(); |             cleanup(); | ||||||
|           }; |           }; | ||||||
| 
 | 
 | ||||||
|           tok = setTimeout(function () { |           tok = setTimeout(function () { | ||||||
|             var err = new Error("the iframe request did not complete within 15 seconds"); |             var err = new Error( | ||||||
|  |               "the '" + windowType + "' request did not complete within " + Math.round(timeout / 1000) + "s" | ||||||
|  |             ); | ||||||
|             err.code = "E_TIMEOUT"; |             err.code = "E_TIMEOUT"; | ||||||
|             reject(err); |             reject(err); | ||||||
|             cleanup(); |             cleanup(); | ||||||
|           }, opts.timeout || 15 * 1000); |           }, timeout); | ||||||
| 
 | 
 | ||||||
|           if ('background' === opts.windowType) { |           setTimeout(function () { | ||||||
|  |             if (!OAUTH3._browser._frames[state]) { | ||||||
|  |               reject(new Error("TODO: open the iframe first and discover oauth3 directives before popup")); | ||||||
|  |               cleanup(); | ||||||
|  |             } | ||||||
|  |           }, 0); | ||||||
|  | 
 | ||||||
|  |           if ('background' === windowType) { | ||||||
|             if (previousFrame) { |             if (previousFrame) { | ||||||
|               previousFrame.location = url; |               previousFrame.location = url; | ||||||
|               //promise = previousFrame.promise;
 |               //promise = previousFrame.promise;
 | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|               OAUTH3._browser._iframe.insert(url, state, opts); |               OAUTH3._browser._frames[state] = OAUTH3._browser.iframe(url, state, opts); | ||||||
|             } |             } | ||||||
|           } else if ('popup' === opts.windowType) { |           } else if ('popup' === windowType) { | ||||||
|             if (previousFrame) { |             if (previousFrame) { | ||||||
|               previousFrame.location = url; |               previousFrame.location = url; | ||||||
|               if (opts.debug) { |               if (opts.debug) { | ||||||
| @ -426,9 +448,9 @@ | |||||||
|               } |               } | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|               OAUTH3._browser.frame.open(url, state, opts); |               OAUTH3._browser._frames[state] = OAUTH3._browser.frame(url, state, opts); | ||||||
|             } |             } | ||||||
|           } else if ('inline' === opts.windowType) { |           } else if ('inline' === windowType) { | ||||||
|             // callback function will never execute and would need to redirect back to current page
 |             // callback function will never execute and would need to redirect back to current page
 | ||||||
|             // rather than the callback.html
 |             // rather than the callback.html
 | ||||||
|             url += '&original_url=' + OAUTH3._browser.window.location.href; |             url += '&original_url=' + OAUTH3._browser.window.location.href; | ||||||
| @ -478,72 +500,32 @@ | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     , _frames: {} |     , _frames: {} | ||||||
|     , iframe: { |     , iframe: function (url, state, opts) { | ||||||
|         insert: function (url, state, opts) { |  | ||||||
|           // TODO hidden / non-hidden (via directive even)
 |  | ||||||
|         var framesrc = '<iframe class="js-oauth3-iframe" src="' + url + '" '; |         var framesrc = '<iframe class="js-oauth3-iframe" src="' + url + '" '; | ||||||
|         if (opts.debug) { |         if (opts.debug) { | ||||||
|             framesrc += ' width="800px" height="800px" style="opacity: 0.8;" frameborder="1"'; |           framesrc += ' width="' + (opts.height || 600) + 'px"' | ||||||
|  |             + ' height="' + (opts.width || 720) + 'px"' | ||||||
|  |             + ' style="opacity: 0.8;" frameborder="1"'; | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|           framesrc += ' width="1px" height="1px" frameborder="0"'; |           framesrc += ' width="1px" height="1px" frameborder="0"'; | ||||||
|         } |         } | ||||||
|         framesrc += '></iframe>'; |         framesrc += '></iframe>'; | ||||||
| 
 | 
 | ||||||
|           var frame = OAUTH3._browser._frames[state] = OAUTH3._browser.window.document.createElement('div'); |         var frame = OAUTH3._browser.window.document.createElement('div'); | ||||||
|           OAUTH3._browser._frames[state].innerHTML = framesrc; |         frame.innerHTML = framesrc; | ||||||
|           OAUTH3._browser.window.document.body.appendChild(OAUTH3._browser._frames[state]); |         OAUTH3._browser.window.document.body.appendChild(frame); | ||||||
| 
 | 
 | ||||||
|         return frame; |         return frame; | ||||||
|       } |       } | ||||||
|       } |     , frame: function (url, state, opts) { | ||||||
|     , frame: { |  | ||||||
|         open: function (url, state, opts) { |  | ||||||
|           if (opts.debug) { |  | ||||||
|             opts.timeout = opts.timeout || 15 * 60 * 1000; |  | ||||||
|           } |  | ||||||
| 
 |  | ||||||
|           var promise = new OAUTH3.PromiseA(function (resolve, reject) { |  | ||||||
|             var tok; |  | ||||||
| 
 |  | ||||||
|             function cleanup() { |  | ||||||
|               clearTimeout(tok); |  | ||||||
|               tok = null; |  | ||||||
|               delete window['--oauth3-callback-' + state]; |  | ||||||
|               // close is done later in case the window is reused or self-closes synchronously itself / by parent
 |  | ||||||
|               // (probably won't ever happen, but that's a negotiable implementation detail)
 |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             window['--oauth3-callback-' + state] = function (params) { |  | ||||||
|               console.log('YOLO!!'); |  | ||||||
|               resolve(params); |  | ||||||
|               cleanup(); |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             tok = setTimeout(function () { |  | ||||||
|               var err = new Error("the windowed request did not complete within 3 minutes"); |  | ||||||
|               err.code = "E_TIMEOUT"; |  | ||||||
|               reject(err); |  | ||||||
|               cleanup(); |  | ||||||
|             }, opts.timeout || 3 * 60 * 1000); |  | ||||||
| 
 |  | ||||||
|             setTimeout(function () { |  | ||||||
|               if (!promise.child) { |  | ||||||
|                 reject("TODO: open the iframe first and discover oauth3 directives before popup"); |  | ||||||
|                 cleanup(); |  | ||||||
|               } |  | ||||||
|             }, 0); |  | ||||||
|           }); |  | ||||||
| 
 | 
 | ||||||
|         // TODO allow size changes (via directive even)
 |         // TODO allow size changes (via directive even)
 | ||||||
|           OAUTH3._browser._frames[state] = window.open( |         return window.open( | ||||||
|           url |           url | ||||||
|         , 'oauth3-login-' + (opts.reuseWindow || state) |         , 'oauth3-login-' + (opts.reuseWindow || state) | ||||||
|         , 'height=' + (opts.height || 720) + ',width=' + (opts.width || 620) |         , 'height=' + (opts.height || 720) + ',width=' + (opts.width || 620) | ||||||
|         ); |         ); | ||||||
|           // TODO periodically garbage collect expired handlers from window object
 |  | ||||||
|           return promise; |  | ||||||
|         } |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user