X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F06_net%2F10_XOAuth2.js;h=5f23c6ced529fad16f6574e1d0cef31203a1e2cb;hb=HEAD;hp=91f7f67663d0c472e74d0be6867a4857bbed930d;hpb=7973f3ff61f1ef5bd9732f527b175010d0c0971b;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/06_net/10_XOAuth2.js b/0.6.x/js/06_net/10_XOAuth2.js index 91f7f67..5f23c6c 100644 --- a/0.6.x/js/06_net/10_XOAuth2.js +++ b/0.6.x/js/06_net/10_XOAuth2.js @@ -1,13 +1,12 @@ -//{+oauth2"OAuth2 サービスの定義"(OAuth2外部サービスを定義し、認可プロセス・xhrの署名を自動化します)[+xhr] -var X_NET_OAUTH2_detection = new Function( 'w', 'try{return w.location.search}catch(e){}' ), - X_NET_OAUTH2_authorizationWindow, - X_NET_OAUTH2_authorizationTimerID; +//{+oauth2"OAuth2 サービスの定義"(OAuth2外部サービスを定義し、認可プロセス・xhrの署名を自動化します)[+xhr,+window] +var X_OAUTH2_authWindow, + X_OAUTH2_authTimerID; /** * イベント *
- *
X.Event.NEED_AUTH
window を popup して認可を行う必要あり。ポインターイベント内で oauth2.requestAuth() を呼ぶ。 + *
X.Event.NEED_AUTH
window を popup して認可を行う必要あり。ポインターイベント内で oauth2.requestAuth() を呼ぶ。このイベントをキャンセルすると *
X.Event.CANCELED
認可 window が閉じられた。([x]等でウインドウが閉じられた、oauth2.cancelAuth() が呼ばれた) *
X.Event.SUCCESS
認可 window でユーザーが認可し、続いてコードの認可が済んだ。 *
X.Event.ERROR
コードの認可のエラー、リフレッシュトークンのエラー、ネットワークエラー @@ -74,7 +73,7 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( }; // TODO canUse gadgetProxy - this[ 'listen' ]( [ X_EVENT_KILL_INSTANCE, X_EVENT_SUCCESS, X_EVENT_ERROR, X_EVENT_NEED_AUTH ], X_NET_OAUTH2_handleEvent ); + this[ 'listen' ]( [ X_EVENT_KILL_INSTANCE, X_EVENT_SUCCESS, X_EVENT_ERROR, X_EVENT_NEED_AUTH ], X_OAUTH2_handleEvent ); }, /** @@ -94,38 +93,53 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( /** * 認可用 window をポップアップする。ポップアップブロックが働かないように必ず pointer event 内で呼ぶこと。 + *
+ *
1 :
認可用 window がポップアップ中(自身) + *
2 :
コードを認可中 + *
3 :
トークンのリフレッシュ中 + *
4 :
接続 + *
5 :
他のOAuth2サービスの認可用 window がポップアップ中 + *
+ * @return {number} */ 'requestAuth' : function(){ - var url, w, h; + var e = X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length - 1 ], + w, h, pair; + // TODO pointer event 内か?チェック + if( !e || !e[ 'pointerType' ] ){ + alert( 'タッチイベント以外での popup! ' + ( e ? e.type : '' ) ); + return; + }; + // 二つ以上の popup を作らない - if( X_NET_OAUTH2_authorizationWindow ) return; + if( X_OAUTH2_authWindow ) return; pair = X_Pair_get( this ); if( pair.net || pair.oauth2State ) return; - - url = pair[ 'authorizeEndpoint' ]; + w = pair[ 'authorizeWindowWidth' ] || 500; h = pair[ 'authorizeWindowHeight' ] || 500; + + X_OAUTH2_authWindow = X_Window( { + 'url' : X_URL_create( pair[ 'authorizeEndpoint' ], + { + 'response_type' : 'code', + 'client_id' : pair[ 'clientID' ], + 'redirect_uri' : pair[ 'redirectURI' ], + 'scope' : ( pair[ 'scopes' ] || [] ).join( ' ' ) + } + ), + 'name' : 'oauthauthorize', + 'params' : 'width=' + w + + ',height=' + h + + ',left=' + ( screen.width - w ) / 2 + + ',top=' + ( screen.height - h ) / 2 + + ',menubar=no,toolbar=no' + } )[ 'listen' ]( X_EVENT_UNLOAD, this, X_OAuth2_detectAuthPopup ); - X_NET_OAUTH2_authorizationWindow = window.open( - X_URL_create( url, - { - 'response_type' : 'code', - 'client_id' : pair[ 'clientID' ], - 'redirect_uri' : pair[ 'redirectURI' ], - 'scope' : ( pair[ 'scopes' ] || [] ).join(' ') - } - ), - 'oauthauthorize', - 'width=' + w - + ',height=' + h - + ',left=' + ( screen.width - w ) / 2 - + ',top=' + ( screen.height - h ) / 2 - + ',menubar=no,toolbar=no'); - - X_NET_OAUTH2_authorizationTimerID = X_Timer_add( 333, 0, this, X_Net_OAuth2_detectAuthPopup ); + X_OAUTH2_authTimerID = X_Timer_add( 333, 0, this, X_OAuth2_detectAuthPopup ); pair.oauth2State = 1; @@ -148,17 +162,13 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( }; // http://kojikoji75.hatenablog.com/entry/2013/12/15/223839 - if( X_NET_OAUTH2_authorizationWindow ){ - if( 9 < X_UA[ 'IEHost' ] ){ - X_NET_OAUTH2_authorizationWindow.close(); - } else { - X_NET_OAUTH2_authorizationWindow.open( 'about:blank', '_self' ).close(); - }; - X_NET_OAUTH2_authorizationWindow = null; + if( X_OAUTH2_authWindow ){ + X_OAUTH2_authWindow[ 'kill' ](); + X_OAUTH2_authWindow = null; }; - X_NET_OAUTH2_authorizationTimerID && X_Timer_remove( X_NET_OAUTH2_authorizationTimerID ); - X_NET_OAUTH2_authorizationTimerID = 0; + X_OAUTH2_authTimerID && X_Timer_remove( X_OAUTH2_authTimerID ); + X_OAUTH2_authTimerID = 0; this[ 'asyncDispatch' ]( X_EVENT_CANCELED ); }, @@ -199,14 +209,14 @@ X[ 'OAuth2' ] = X_EventDispatcher[ 'inherits' ]( 'Content-Type' : 'application/x-www-form-urlencoded' }, 'test' : 'gadget' // canuse - } ).listenOnce( [ X_EVENT_SUCCESS, X_EVENT_ERROR ], this, X_Net_OAuth2_responceHandler ); + } ).listenOnce( [ X_EVENT_SUCCESS, X_EVENT_ERROR ], this, X_OAuth2_responceHandler ); this[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, message : 'Start to refresh token.' } ); } } ); -function X_NET_OAUTH2_handleEvent( e ){ +function X_OAUTH2_handleEvent( e ){ var pair = X_Pair_get( this ); switch( e.type ){ @@ -227,41 +237,35 @@ function X_NET_OAUTH2_handleEvent( e ){ }; }; -function X_Net_OAuth2_detectAuthPopup(){ - var closed, search, pair = X_Pair_get( this ); - - if( X_NET_OAUTH2_authorizationWindow.closed ){ - pair.oauth2State = 0; - closed = true; +function X_OAuth2_detectAuthPopup( e ){ + var pair = X_Pair_get( this ), + status, search; + if( X_OAUTH2_authWindow[ 'closed' ]() ){ + status = 0; this[ 'asyncDispatch' ]( X_EVENT_CANCELED ); } else - if( search = X_NET_OAUTH2_detection( X_NET_OAUTH2_authorizationWindow ) ){ - pair = X_Pair_get( this ); - pair.code = X_URL_ParamToObj( search.slice( 1 ) )[ 'code' ]; - - if( 9 < X_UA[ 'IEHost' ] ){ - X_NET_OAUTH2_authorizationWindow.close(); - } else { - X_NET_OAUTH2_authorizationWindow.open( 'about:blank', '_self' ).close(); - }; - closed = true; - - X_Net_OAuth2_authorizationCode( this, pair ); - - pair.oauth2State = 2; + if( search = X_OAUTH2_authWindow[ 'find' ]( 'location>search' ) ){ + pair = X_Pair_get( this ); + pair.code = X_URL_paramToObj( search.slice( 1 ) )[ 'code' ]; + status = 2; + X_OAuth2_authorizationCode( this, pair ); this[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, message : 'Get code success, then authorization code.' } ); }; - if( closed ){ - X_NET_OAUTH2_authorizationWindow = null; - X_NET_OAUTH2_authorizationTimerID = 0; + if( 0 <= status ){ + pair = pair || X_Pair_get( this ); + pair.oauth2State = status; + + X_OAUTH2_authWindow[ 'kill' ](); + X_OAUTH2_authWindow = null; + X_OAUTH2_authTimerID = X_Timer_remove( X_OAUTH2_authTimerID ); - return X_Callback_UN_LISTEN; + return X_CALLBACK_UN_LISTEN; }; }; -function X_Net_OAuth2_authorizationCode( oauth2, pair ){ +function X_OAuth2_authorizationCode( oauth2, pair ){ pair.net = X.Net( { 'xhr' : pair[ 'tokenEndpoint' ], 'postdata' : X_URL_objToParam({ @@ -277,10 +281,10 @@ function X_Net_OAuth2_authorizationCode( oauth2, pair ){ 'Content-Type' : 'application/x-www-form-urlencoded' }, 'test' : 'gadget' - } ).listenOnce( [ X_EVENT_SUCCESS, X_EVENT_ERROR ], oauth2, X_Net_OAuth2_responceHandler ); + } ).listenOnce( [ X_EVENT_SUCCESS, X_EVENT_ERROR ], oauth2, X_OAuth2_responceHandler ); }; -function X_Net_OAuth2_responceHandler( e ){ +function X_OAuth2_responceHandler( e ){ var data = e.response, pair = X_Pair_get( this ), isRefresh = pair.oauth2State === 3; @@ -339,7 +343,7 @@ function X_Net_OAuth2_responceHandler( e ){ X_OAuth2_setAuthMechanism( this, 'param' ); this[ 'asyncDispatch' ]( { type : X_EVENT_PROGRESS, message : 'Refresh access token failed. retry header -> param. ' } ); // retry - X_Net_OAuth2_authorizationCode( this, pair ); + X_OAuth2_authorizationCode( this, pair ); }; break; }; @@ -357,11 +361,11 @@ function X_NET_OAUTH2_onXHR401Error( oauth2, e ){ }; // http://d.hatena.ne.jp/ritou/20110402/1301679908 - if ( bearerParams && bearerParams.indexOf( ' error=' ) === -1 ) { // bearerParams.error == undefined + if( bearerParams && bearerParams.indexOf( ' error=' ) === -1 ){ // bearerParams.error == undefined pair.oauth2State = 0; oauth2[ 'asyncDispatch' ]( X_EVENT_NEED_AUTH ); } else - if ((( bearerParams && bearerParams.indexOf( 'invalid_token' ) !== -1 ) || !headersExposed) && X_OAuth2_getRefreshToken( oauth2 ) ) { + if( ( ( bearerParams && bearerParams.indexOf( 'invalid_token' ) !== -1 ) || !headersExposed ) && X_OAuth2_getRefreshToken( oauth2 ) ){ X_OAuth2_removeAccessToken( oauth2 ); // It doesn't work any more. pair.oauth2State = 3; oauth2[ 'refreshToken' ](); @@ -390,11 +394,11 @@ function X_NET_OAUTH2_updateRequest( oauth2, request ){ function X_OAuth2_getAccessToken( that ){ return X_OAuth2_updateLocalStorage( '', that, 'accessToken' ); } function X_OAuth2_getRefreshToken( that ){ return X_OAuth2_updateLocalStorage( '', that, 'refreshToken' ); } -function X_OAuth2_getAccessTokenExpiry( that ){ return parseInt( X_OAuth2_updateLocalStorage( '', that, 'tokenExpiry' ) ) || 0; } +function X_OAuth2_getAccessTokenExpiry( that ){ return parseFloat( X_OAuth2_updateLocalStorage( '', that, 'tokenExpiry' ) ) || 0; } function X_OAuth2_getAuthMechanism( that ){ // TODO use gadget | flash ... // IE's XDomainRequest doesn't support sending headers, so don't try. - return ( X_NET_currentWrapper === X_NET_XHRWrapper ) && X_Net_XHR_createXDR ? 'param' : X_OAuth2_updateLocalStorage( '', that, 'AuthMechanism' ); + return ( X_NET_currentWrapper === X_XHR ) && X_XHR_createXDR ? 'param' : X_OAuth2_updateLocalStorage( '', that, 'AuthMechanism' ); } function X_OAuth2_setAccessToken( that, value ){ X_OAuth2_updateLocalStorage( '+', that, 'accessToken' , value); } function X_OAuth2_setRefreshToken( that, value ){ X_OAuth2_updateLocalStorage( '+', that, 'refreshToken', value); } @@ -410,7 +414,7 @@ function X_OAuth2_updateLocalStorage( cmd, that, name, value ){ var action = cmd === '+' ? 'setItem' : cmd === '-' ? 'removeItem' : 'getItem', pair; - if( window.localStorage ){ + if( window.localStorage ){ // TODO http://qiita.com/narikei/items/f55fb9cb398beac52ea9 return window.localStorage[ action ]( X_Pair_get( that )[ 'clientID' ] + name, value ); };