-//{+oauth2"OAuth2 サービスの定義"(OAuth2外部サービスを定義し、認可プロセス・xhrの署名を自動化します)[+xhr]
-var X_NET_OAUTH2_authorizationWindow,
- X_NET_OAUTH2_authorizationTimerID;
+//{+oauth2"OAuth2 サービスの定義"(OAuth2外部サービスを定義し、認可プロセス・xhrの署名を自動化します)[+xhr,+window]
+var X_OAUTH2_authWindow,
+ X_OAUTH2_authTimerID;
/**
* イベント
* <dl>
- * <dt>X.Event.NEED_AUTH<dd>window を popup して認可を行う必要あり。ポインターイベント内で oauth2.requestAuth() を呼ぶ。
+ * <dt>X.Event.NEED_AUTH<dd>window を popup して認可を行う必要あり。ポインターイベント内で oauth2.requestAuth() を呼ぶ。このイベントをキャンセルすると
* <dt>X.Event.CANCELED<dd>認可 window が閉じられた。([x]等でウインドウが閉じられた、oauth2.cancelAuth() が呼ばれた)
* <dt>X.Event.SUCCESS<dd>認可 window でユーザーが認可し、続いてコードの認可が済んだ。
* <dt>X.Event.ERROR<dd>コードの認可のエラー、リフレッシュトークンのエラー、ネットワークエラー
};
// 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 );
},
/**
/**
* 認可用 window をポップアップする。ポップアップブロックが働かないように必ず pointer event 内で呼ぶこと。
+ * <dl>
+ * <dt>1 : <dd>認可用 window がポップアップ中(自身)
+ * <dt>2 : <dd>コードを認可中
+ * <dt>3 : <dd>トークンのリフレッシュ中
+ * <dt>4 : <dd>接続
+ * <dt>5 : <dd>他のOAuth2サービスの認可用 window がポップアップ中
+ * </dl>
+ * @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;
};
// 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 );
},
'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 ){
};
};
-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_Script_try( X_Object_find, [ X_NET_OAUTH2_authorizationWindow, 'location>search' ] ) ){
- pair = X_Pair_get( this );
+ if( search = X_OAUTH2_authWindow[ 'find' ]( 'location>search' ) ){
+ 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;
+ 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;
};
};
-function X_Net_OAuth2_authorizationCode( oauth2, pair ){
+function X_OAuth2_authorizationCode( oauth2, pair ){
pair.net = X.Net( {
'xhr' : pair[ 'tokenEndpoint' ],
'postdata' : X_URL_objToParam({
'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;
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;
};
};
// 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' ]();
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.