@@ -12,6 +12,10 @@ import {
1212import { ActivatedRoute , Router } from '@angular/router' ;
1313import { Observable } from 'rxjs/Observable' ;
1414import 'rxjs/add/operator/share' ;
15+ import 'rxjs/add/observable/interval' ;
16+ import 'rxjs/add/observable/fromEvent' ;
17+ import 'rxjs/add/operator/pluck' ;
18+ import 'rxjs/add/operator/filter' ;
1519
1620import {
1721 SignInData ,
@@ -107,7 +111,8 @@ export class Angular2TokenService implements CanActivate {
107111 oAuthPaths : {
108112 github : 'auth/github'
109113 } ,
110-
114+ oAuthCallbackPath : 'oauth_callback' ,
115+ oAuthWindowType : 'newWindow' ,
111116 globalOptions : {
112117 headers : {
113118 'Content-Type' : 'application/json' ,
@@ -166,13 +171,23 @@ export class Angular2TokenService implements CanActivate {
166171
167172 signInOAuth ( oAuthType : string ) {
168173
169- let oAuthPath : string ;
174+ let oAuthPath : string = this . _getOAuthPath ( oAuthType ) ;
175+ let callbackUrl : string = `${ window . location . origin } /${ this . _options . oAuthCallbackPath } ` ;
176+ let oAuthWindowType : string = this . _options . oAuthWindowType ;
177+ let authUrl : string = this . _buildOAuthUrl ( oAuthPath , callbackUrl , oAuthWindowType ) ;
170178
171- if ( oAuthType == 'github' ) {
172- oAuthPath = this . _options . oAuthPaths . github
179+ if ( oAuthWindowType == 'newWindow' ) {
180+ let popup = window . open ( authUrl , '_blank' , 'closebuttoncaption=Cancel' ) ;
181+ return this . _requestCredentialsViaPostMessage ( popup ) ;
182+ } else if ( oAuthWindowType == 'sameWindow' ) {
183+ window . location . href = authUrl ;
184+ } else {
185+ throw `Unsupported oAuthWindowType "${ oAuthWindowType } "` ;
173186 }
187+ }
174188
175- window . open ( this . _constructUserPath ( ) + oAuthPath ) ;
189+ processOAuthCallback ( ) {
190+ this . _getAuthDataFromParams ( ) ;
176191 }
177192
178193 // Sign out request and delete storage
@@ -385,7 +400,7 @@ export class Angular2TokenService implements CanActivate {
385400 if ( this . _activatedRoute . queryParams ) // Fix for Testing, needs to be removed later
386401 this . _activatedRoute . queryParams . subscribe ( queryParams => {
387402 let authData : AuthData = {
388- accessToken : queryParams [ 'token' ] ,
403+ accessToken : queryParams [ 'token' ] || queryParams [ 'auth_token' ] ,
389404 client : queryParams [ 'client_id' ] ,
390405 expiry : queryParams [ 'expiry' ] ,
391406 tokenType : 'Bearer' ,
@@ -397,6 +412,18 @@ export class Angular2TokenService implements CanActivate {
397412 } ) ;
398413 }
399414
415+ private _parseAuthDataFromPostMessage ( data : any ) {
416+ let authData : AuthData = {
417+ accessToken : data [ 'auth_token' ] ,
418+ client : data [ 'client_id' ] ,
419+ expiry : data [ 'expiry' ] ,
420+ tokenType : 'Bearer' ,
421+ uid : data [ 'uid' ]
422+ } ;
423+
424+ this . _setAuthData ( authData ) ;
425+ }
426+
400427 // Write auth data to storage
401428 private _setAuthData ( authData : AuthData ) {
402429
@@ -476,4 +503,49 @@ export class Angular2TokenService implements CanActivate {
476503 else
477504 return this . _options . apiPath + '/' ;
478505 }
506+
507+ private _getOAuthPath ( oAuthType : string ) : string {
508+ let oAuthPath : string ;
509+
510+ oAuthPath = this . _options . oAuthPaths [ oAuthType ] ;
511+ if ( oAuthPath == null ) {
512+ oAuthPath = `/auth/${ oAuthType } ` ;
513+ }
514+ return oAuthPath ;
515+ }
516+
517+ private _buildOAuthUrl ( oAuthPath : string , callbackUrl : string , windowType : string ) : string {
518+ let url : string ;
519+
520+ url = `${ window . location . origin } /${ oAuthPath } ` ;
521+ url += `?omniauth_window_type=${ windowType } ` ;
522+ url += `&auth_origin_url=${ encodeURIComponent ( callbackUrl ) } ` ;
523+ if ( this . _currentUserType != null ) {
524+ url += `&resource_class=${ this . _currentUserType . name } ` ;
525+ }
526+ return url ;
527+ }
528+
529+ private _requestCredentialsViaPostMessage ( authWindow : any ) : Observable < any > {
530+ let poller_observ = Observable . interval ( 500 ) ;
531+ let response_observ = Observable . fromEvent ( window , 'message' )
532+ . pluck ( 'data' )
533+ . filter ( this . _oauthWindowResponseFilter ) ;
534+
535+ let response_subscription = response_observ . subscribe ( this . _parseAuthDataFromPostMessage . bind ( this ) ) ;
536+ let poller_subscription = poller_observ . subscribe ( ( ) => {
537+ if ( authWindow . closed ) {
538+ poller_subscription . unsubscribe ( ) ;
539+ } else {
540+ authWindow . postMessage ( 'requestCredentials' , '*' ) ;
541+ }
542+ } ) ;
543+ return response_observ ;
544+ }
545+
546+ private _oauthWindowResponseFilter ( data : any ) {
547+ if ( data . message == 'deliverCredentials' || data . message == 'authFailure' ) {
548+ return data ;
549+ }
550+ }
479551}
0 commit comments