1
- import { Injectable , NgZone , Optional , OnDestroy } from '@angular/core' ;
1
+ import { Injectable , NgZone , Optional , OnDestroy , Inject } from '@angular/core' ;
2
2
import { HttpClient , HttpHeaders , HttpParams } from '@angular/common/http' ;
3
3
import { Observable , Subject , Subscription , of , race , from } from 'rxjs' ;
4
4
import { filter , delay , first , tap , map , switchMap , debounceTime } from 'rxjs/operators' ;
5
+ import { DOCUMENT } from '@angular/common' ;
5
6
6
7
import {
7
8
ValidationHandler ,
@@ -91,6 +92,7 @@ export class OAuthService extends AuthConfig implements OnDestroy {
91
92
protected urlHelper : UrlHelperService ,
92
93
protected logger : OAuthLogger ,
93
94
@Optional ( ) protected crypto : HashHandler ,
95
+ @Inject ( DOCUMENT ) private document : Document ,
94
96
) {
95
97
super ( ) ;
96
98
@@ -733,7 +735,8 @@ export class OAuthService extends AuthConfig implements OnDestroy {
733
735
tokenResponse . access_token ,
734
736
tokenResponse . refresh_token ,
735
737
tokenResponse . expires_in ,
736
- tokenResponse . scope
738
+ tokenResponse . scope ,
739
+ this . extractRecognizedCustomParameters ( tokenResponse )
737
740
) ;
738
741
739
742
this . eventsSubject . next ( new OAuthSuccessEvent ( 'token_received' ) ) ;
@@ -810,7 +813,8 @@ export class OAuthService extends AuthConfig implements OnDestroy {
810
813
tokenResponse . access_token ,
811
814
tokenResponse . refresh_token ,
812
815
tokenResponse . expires_in ,
813
- tokenResponse . scope
816
+ tokenResponse . scope ,
817
+ this . extractRecognizedCustomParameters ( tokenResponse )
814
818
) ;
815
819
816
820
this . eventsSubject . next ( new OAuthSuccessEvent ( 'token_received' ) ) ;
@@ -1400,7 +1404,8 @@ export class OAuthService extends AuthConfig implements OnDestroy {
1400
1404
accessToken : string ,
1401
1405
refreshToken : string ,
1402
1406
expiresIn : number ,
1403
- grantedScopes : String
1407
+ grantedScopes : String ,
1408
+ customParameters ?: Map < string , string >
1404
1409
) : void {
1405
1410
this . _storage . setItem ( 'access_token' , accessToken ) ;
1406
1411
if ( grantedScopes ) {
@@ -1417,6 +1422,11 @@ export class OAuthService extends AuthConfig implements OnDestroy {
1417
1422
if ( refreshToken ) {
1418
1423
this . _storage . setItem ( 'refresh_token' , refreshToken ) ;
1419
1424
}
1425
+ if ( customParameters ) {
1426
+ customParameters . forEach ( ( value : string , key : string ) => {
1427
+ this . _storage . setItem ( key , value ) ;
1428
+ } ) ;
1429
+ }
1420
1430
}
1421
1431
1422
1432
/**
@@ -1455,7 +1465,7 @@ export class OAuthService extends AuthConfig implements OnDestroy {
1455
1465
options . customHashFragment . substring ( 1 ) :
1456
1466
window . location . search ;
1457
1467
1458
- const parts = this . getCodePartsFromUrl ( window . location . search ) ;
1468
+ const parts = this . getCodePartsFromUrl ( querySource ) ;
1459
1469
1460
1470
const code = parts [ 'code' ] ;
1461
1471
const state = parts [ 'state' ] ;
@@ -1580,7 +1590,8 @@ export class OAuthService extends AuthConfig implements OnDestroy {
1580
1590
tokenResponse . access_token ,
1581
1591
tokenResponse . refresh_token ,
1582
1592
tokenResponse . expires_in ,
1583
- tokenResponse . scope ) ;
1593
+ tokenResponse . scope ,
1594
+ this . extractRecognizedCustomParameters ( tokenResponse ) ) ;
1584
1595
1585
1596
if ( this . oidc && tokenResponse . id_token ) {
1586
1597
this . processIdToken ( tokenResponse . id_token , tokenResponse . access_token ) .
@@ -2084,6 +2095,16 @@ export class OAuthService extends AuthConfig implements OnDestroy {
2084
2095
return false ;
2085
2096
}
2086
2097
2098
+ /**
2099
+ * Retrieve a saved custom property of the TokenReponse object. Only if predefined in authconfig.
2100
+ */
2101
+ public getCustomTokenResponseProperty ( requestedProperty : string ) : any {
2102
+ return this . _storage && this . config . customTokenParameters
2103
+ && ( this . config . customTokenParameters . indexOf ( requestedProperty ) >= 0 )
2104
+ && this . _storage . getItem ( requestedProperty ) !== null
2105
+ ? JSON . parse ( this . _storage . getItem ( requestedProperty ) ) : null ;
2106
+ }
2107
+
2087
2108
/**
2088
2109
* Returns the auth-header that can be used
2089
2110
* to transmit the access_token to a service
@@ -2095,10 +2116,11 @@ export class OAuthService extends AuthConfig implements OnDestroy {
2095
2116
/**
2096
2117
* Removes all tokens and logs the user out.
2097
2118
* If a logout url is configured, the user is
2098
- * redirected to it.
2119
+ * redirected to it with optional state parameter .
2099
2120
* @param noRedirectToLogoutUrl
2121
+ * @param state
2100
2122
*/
2101
- public logOut ( noRedirectToLogoutUrl = false ) : void {
2123
+ public logOut ( noRedirectToLogoutUrl = false , state = '' ) : void {
2102
2124
const id_token = this . getIdToken ( ) ;
2103
2125
this . _storage . removeItem ( 'access_token' ) ;
2104
2126
this . _storage . removeItem ( 'id_token' ) ;
@@ -2111,7 +2133,9 @@ export class OAuthService extends AuthConfig implements OnDestroy {
2111
2133
this . _storage . removeItem ( 'access_token_stored_at' ) ;
2112
2134
this . _storage . removeItem ( 'granted_scopes' ) ;
2113
2135
this . _storage . removeItem ( 'session_state' ) ;
2114
-
2136
+ if ( this . config . customTokenParameters ) {
2137
+ this . config . customTokenParameters . forEach ( customParam => this . _storage . removeItem ( customParam ) ) ;
2138
+ }
2115
2139
this . silentRefreshSubject = null ;
2116
2140
2117
2141
this . eventsSubject . next ( new OAuthInfoEvent ( 'logout' ) ) ;
@@ -2151,6 +2175,10 @@ export class OAuthService extends AuthConfig implements OnDestroy {
2151
2175
const postLogoutUrl = this . postLogoutRedirectUri || this . redirectUri ;
2152
2176
if ( postLogoutUrl ) {
2153
2177
params = params . set ( 'post_logout_redirect_uri' , postLogoutUrl ) ;
2178
+
2179
+ if ( state ) {
2180
+ params = params . set ( 'state' , state ) ;
2181
+ }
2154
2182
}
2155
2183
2156
2184
logoutUrl =
@@ -2180,14 +2208,14 @@ export class OAuthService extends AuthConfig implements OnDestroy {
2180
2208
this . clearIdTokenTimer ( ) ;
2181
2209
2182
2210
this . removeSilentRefreshEventListener ( ) ;
2183
- const silentRefreshFrame = document . getElementById ( this . silentRefreshIFrameName ) ;
2211
+ const silentRefreshFrame = this . document . getElementById ( this . silentRefreshIFrameName ) ;
2184
2212
if ( silentRefreshFrame ) {
2185
2213
silentRefreshFrame . remove ( ) ;
2186
2214
}
2187
2215
2188
2216
this . stopSessionCheckTimer ( ) ;
2189
2217
this . removeSessionCheckEventListener ( ) ;
2190
- const sessionCheckFrame = document . getElementById ( this . sessionCheckIFrameName ) ;
2218
+ const sessionCheckFrame = this . document . getElementById ( this . sessionCheckIFrameName ) ;
2191
2219
if ( sessionCheckFrame ) {
2192
2220
sessionCheckFrame . remove ( ) ;
2193
2221
}
@@ -2305,8 +2333,21 @@ export class OAuthService extends AuthConfig implements OnDestroy {
2305
2333
2306
2334
const verifier = await this . createNonce ( ) ;
2307
2335
const challengeRaw = await this . crypto . calcHash ( verifier , 'sha-256' ) ;
2308
- const challange = base64UrlEncode ( challengeRaw ) ;
2309
-
2310
- return [ challange , verifier ] ;
2336
+ const challenge = base64UrlEncode ( challengeRaw ) ;
2337
+
2338
+ return [ challenge , verifier ] ;
2339
+ }
2340
+
2341
+ private extractRecognizedCustomParameters ( tokenResponse : TokenResponse ) : Map < string , string > {
2342
+ let foundParameters : Map < string , string > = new Map < string , string > ( ) ;
2343
+ if ( ! this . config . customTokenParameters ) {
2344
+ return foundParameters ;
2345
+ }
2346
+ this . config . customTokenParameters . forEach ( ( recognizedParameter : string ) => {
2347
+ if ( tokenResponse [ recognizedParameter ] ) {
2348
+ foundParameters . set ( recognizedParameter , JSON . stringify ( tokenResponse [ recognizedParameter ] ) ) ;
2349
+ }
2350
+ } ) ;
2351
+ return foundParameters ;
2311
2352
}
2312
2353
}
0 commit comments