@@ -632,73 +632,98 @@ export class OAuthService extends AuthConfig {
632
632
password : string ,
633
633
headers : HttpHeaders = new HttpHeaders ( )
634
634
) : Promise < object > {
635
+ const parameters = {
636
+ username : userName ,
637
+ password : password ,
638
+ } ;
639
+ return this . fetchTokenUsingGrant ( 'password' , parameters , headers ) ;
640
+ }
641
+
642
+ /**
643
+ * Uses a custom grant type to retrieve tokens.
644
+ * @param grantType Grant type.
645
+ * @param parameters Parameters to pass.
646
+ * @param headers Optional additional HTTP headers.
647
+ */
648
+ public fetchTokenUsingGrant ( grantType : string , parameters : object , headers : HttpHeaders = new HttpHeaders ( ) ) : Promise < TokenResponse > {
635
649
if ( ! this . validateUrlForHttps ( this . tokenEndpoint ) ) {
636
650
throw new Error (
637
651
'tokenEndpoint must use http, or config value for property requireHttps must allow http'
638
652
) ;
639
653
}
640
654
641
- return new Promise ( ( resolve , reject ) => {
642
- /**
643
- * A `HttpParameterCodec` that uses `encodeURIComponent` and `decodeURIComponent` to
644
- * serialize and parse URL parameter keys and values.
645
- *
646
- * @stable
647
- */
648
- let params = new HttpParams ( { encoder : new WebHttpUrlEncodingCodec ( ) } )
649
- . set ( 'grant_type' , 'password' )
650
- . set ( 'scope' , this . scope )
651
- . set ( 'username' , userName )
652
- . set ( 'password' , password ) ;
653
-
654
- if ( this . useHttpBasicAuthForPasswordFlow ) {
655
- const header = btoa ( `${ this . clientId } :${ this . dummyClientSecret } ` ) ;
656
- headers = headers . set (
657
- 'Authorization' ,
658
- 'Basic ' + header ) ;
659
- }
655
+ /**
656
+ * A `HttpParameterCodec` that uses `encodeURIComponent` and `decodeURIComponent` to
657
+ * serialize and parse URL parameter keys and values.
658
+ *
659
+ * @stable
660
+ */
661
+ let params = new HttpParams ( { encoder : new WebHttpUrlEncodingCodec ( ) } )
662
+ . set ( 'grant_type' , grantType )
663
+ . set ( 'scope' , this . scope ) ;
660
664
661
- if ( ! this . useHttpBasicAuthForPasswordFlow ) {
662
- params = params . set ( 'client_id' , this . clientId ) ;
663
- }
665
+ if ( this . useHttpBasicAuthForPasswordFlow ) {
666
+ const header = btoa ( `${ this . clientId } :${ this . dummyClientSecret } ` ) ;
667
+ headers = headers . set (
668
+ 'Authorization' ,
669
+ 'Basic ' + header ) ;
670
+ }
664
671
665
- if ( ! this . useHttpBasicAuthForPasswordFlow && this . dummyClientSecret ) {
666
- params = params . set ( 'client_secret ' , this . dummyClientSecret ) ;
667
- }
672
+ if ( ! this . useHttpBasicAuthForPasswordFlow ) {
673
+ params = params . set ( 'client_id ' , this . clientId ) ;
674
+ }
668
675
669
- if ( this . customQueryParams ) {
670
- for ( const key of Object . getOwnPropertyNames ( this . customQueryParams ) ) {
671
- params = params . set ( key , this . customQueryParams [ key ] ) ;
672
- }
676
+ if ( ! this . useHttpBasicAuthForPasswordFlow && this . dummyClientSecret ) {
677
+ params = params . set ( 'client_secret' , this . dummyClientSecret ) ;
678
+ }
679
+
680
+ if ( this . customQueryParams ) {
681
+ for ( const key of Object . getOwnPropertyNames ( this . customQueryParams ) ) {
682
+ params = params . set ( key , this . customQueryParams [ key ] ) ;
673
683
}
684
+ }
674
685
675
- headers = headers . set (
676
- 'Content-Type' ,
677
- 'application/x-www-form-urlencoded'
678
- ) ;
686
+ // set explicit parameters last, to allow overwriting
687
+ for ( const key of Object . keys ( parameters ) ) {
688
+ params = params . set ( key , parameters [ key ] ) ;
689
+ }
679
690
680
- this . http
681
- . post < TokenResponse > ( this . tokenEndpoint , params , { headers } )
682
- . subscribe (
683
- tokenResponse => {
684
- this . debug ( 'tokenResponse' , tokenResponse ) ;
685
- this . storeAccessTokenResponse (
686
- tokenResponse . access_token ,
687
- tokenResponse . refresh_token ,
688
- tokenResponse . expires_in ,
689
- tokenResponse . scope
690
- ) ;
691
+ headers = headers . set (
692
+ 'Content-Type' ,
693
+ 'application/x-www-form-urlencoded'
694
+ ) ;
691
695
692
- this . eventsSubject . next ( new OAuthSuccessEvent ( 'token_received' ) ) ;
693
- resolve ( tokenResponse ) ;
694
- } ,
695
- err => {
696
- this . logger . error ( 'Error performing password flow' , err ) ;
697
- this . eventsSubject . next ( new OAuthErrorEvent ( 'token_error' , err ) ) ;
698
- reject ( err ) ;
699
- }
696
+ return this . http
697
+ . post < TokenResponse > ( this . tokenEndpoint , params , { headers } )
698
+ . toPromise ( )
699
+ . then ( tokenResponse => {
700
+ this . debug ( 'tokenResponse' , tokenResponse ) ;
701
+ this . storeAccessTokenResponse (
702
+ tokenResponse . access_token ,
703
+ tokenResponse . refresh_token ,
704
+ tokenResponse . expires_in ,
705
+ tokenResponse . scope
700
706
) ;
701
- } ) ;
707
+
708
+ if ( tokenResponse . id_token ) {
709
+ return this . processIdToken ( tokenResponse . id_token , tokenResponse . access_token )
710
+ . then ( idTokenResult => {
711
+ this . storeIdToken ( idTokenResult ) ;
712
+ return tokenResponse ;
713
+ } ) ;
714
+ }
715
+
716
+ return tokenResponse ;
717
+ } )
718
+ . then ( tokenResponse => {
719
+ this . eventsSubject . next ( new OAuthSuccessEvent ( 'token_received' ) ) ;
720
+ return tokenResponse ;
721
+ } )
722
+ . catch ( err => {
723
+ this . logger . error ( `Error performing ${ grantType } flow` , err ) ;
724
+ this . eventsSubject . next ( new OAuthErrorEvent ( 'token_error' , err ) ) ;
725
+ throw err ;
726
+ } ) ;
702
727
}
703
728
704
729
/**
0 commit comments