@@ -26,6 +26,8 @@ import {
26
26
JWKS_ENDPOINT ,
27
27
OIDC_SCOPE ,
28
28
OIDC_SESSION_IFRAME_ENDPOINT ,
29
+ PKCE_CODE_VERIFIER ,
30
+ PKCE_SEPARATOR ,
29
31
REVOKE_TOKEN_ENDPOINT ,
30
32
SCOPE_TAG ,
31
33
SERVICE_RESOURCES ,
@@ -43,6 +45,7 @@ import {
43
45
FetchResponse ,
44
46
OIDCEndpointsInternal ,
45
47
OIDCProviderMetaData ,
48
+ TemporaryData ,
46
49
TokenResponse
47
50
} from "../models" ;
48
51
import { AuthenticationUtils } from "../utils" ;
@@ -76,9 +79,9 @@ export class AuthenticationHelper<T> {
76
79
if ( configData . overrideWellEndpointConfig ) {
77
80
configData . endpoints &&
78
81
Object . keys ( configData . endpoints ) . forEach ( ( endpointName : string ) => {
79
- const snakeCasedName = endpointName . replace ( / [ A - Z ] / g, ( letter ) => `_${ letter . toLowerCase ( ) } ` ) ;
80
- oidcProviderMetaData [ snakeCasedName ] = configData ?. endpoints
81
- ? configData . endpoints [ endpointName ]
82
+ const snakeCasedName = endpointName . replace ( / [ A - Z ] / g, ( letter ) => `_${ letter . toLowerCase ( ) } ` ) ;
83
+ oidcProviderMetaData [ snakeCasedName ] = configData ?. endpoints
84
+ ? configData . endpoints [ endpointName ]
82
85
: "" ;
83
86
} ) ;
84
87
}
@@ -92,17 +95,17 @@ export class AuthenticationHelper<T> {
92
95
93
96
configData . endpoints &&
94
97
Object . keys ( configData . endpoints ) . forEach ( ( endpointName : string ) => {
95
- const snakeCasedName = endpointName . replace ( / [ A - Z ] / g, ( letter ) => `_${ letter . toLowerCase ( ) } ` ) ;
96
- oidcProviderMetaData [ snakeCasedName ] = configData ?. endpoints ? configData . endpoints [ endpointName ] : "" ;
98
+ const snakeCasedName = endpointName . replace ( / [ A - Z ] / g, ( letter ) => `_${ letter . toLowerCase ( ) } ` ) ;
99
+ oidcProviderMetaData [ snakeCasedName ] = configData ?. endpoints ? configData . endpoints [ endpointName ] : "" ;
97
100
} ) ;
98
101
99
102
const defaultEndpoints = {
100
- [ AUTHORIZATION_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . authorizationEndpoint ,
101
- [ END_SESSION_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . endSessionEndpoint ,
102
- [ JWKS_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . jwksUri ,
103
- [ OIDC_SESSION_IFRAME_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . checkSessionIframe ,
104
- [ REVOKE_TOKEN_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . revocationEndpoint ,
105
- [ TOKEN_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . tokenEndpoint
103
+ [ AUTHORIZATION_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . authorizationEndpoint ,
104
+ [ END_SESSION_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . endSessionEndpoint ,
105
+ [ JWKS_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . jwksUri ,
106
+ [ OIDC_SESSION_IFRAME_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . checkSessionIframe ,
107
+ [ REVOKE_TOKEN_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . revocationEndpoint ,
108
+ [ TOKEN_ENDPOINT ] : configData . serverOrigin + SERVICE_RESOURCES . tokenEndpoint
106
109
} ;
107
110
108
111
return { ...oidcProviderMetaData , ...defaultEndpoints } ;
@@ -120,7 +123,7 @@ export class AuthenticationHelper<T> {
120
123
"validateIdToken" ,
121
124
"JWKS endpoint not found." ,
122
125
"No JWKS endpoint was found in the OIDC provider meta data returned by the well-known endpoint " +
123
- "or the JWKS endpoint passed to the SDK is empty."
126
+ "or the JWKS endpoint passed to the SDK is empty."
124
127
)
125
128
) ;
126
129
}
@@ -145,7 +148,7 @@ export class AuthenticationHelper<T> {
145
148
}
146
149
147
150
const issuer = ( await this . _oidcProviderMetaData ( ) ) . issuer ;
148
- const issuerFromURL = ( await this . resolveWellKnownEndpoint ( ) ) . split ( "/.well-known" ) [ 0 ] ;
151
+ const issuerFromURL = ( await this . resolveWellKnownEndpoint ( ) ) . split ( "/.well-known" ) [ 0 ] ;
149
152
150
153
// Return false if the issuer in the open id config doesn't match
151
154
// the issuer in the well known endpoint URL.
@@ -155,7 +158,7 @@ export class AuthenticationHelper<T> {
155
158
const parsedResponse = await response . json ( ) ;
156
159
157
160
return this . _cryptoHelper
158
- . getJWKForTheIdToken ( idToken . split ( "." ) [ 0 ] , parsedResponse . keys )
161
+ . getJWKForTheIdToken ( idToken . split ( "." ) [ 0 ] , parsedResponse . keys )
159
162
. then ( async ( jwk : any ) => {
160
163
return this . _cryptoHelper
161
164
. isValidIdToken (
@@ -218,12 +221,12 @@ export class AuthenticationHelper<T> {
218
221
const familyName : string = payload . family_name ?? "" ;
219
222
const fullName : string =
220
223
givenName && familyName
221
- ? `${ givenName } ${ familyName } `
224
+ ? `${ givenName } ${ familyName } `
222
225
: givenName
223
- ? givenName
224
- : familyName
225
- ? familyName
226
- : "" ;
226
+ ? givenName
227
+ : familyName
228
+ ? familyName
229
+ : "" ;
227
230
const displayName : string = payload . preferred_username ?? fullName ;
228
231
229
232
return {
@@ -329,4 +332,27 @@ export class AuthenticationHelper<T> {
329
332
return Promise . resolve ( tokenResponse ) ;
330
333
}
331
334
}
335
+
336
+ /**
337
+ * This generates a PKCE key with the right index value.
338
+ *
339
+ * @param {string } userID The userID to identify a user in a multi-user scenario.
340
+ *
341
+ * @returns {string } The PKCE key.
342
+ */
343
+ public async generatePKCEKey ( userID ?: string ) : Promise < string > {
344
+ const tempData : TemporaryData = await this . _dataLayer . getTemporaryData ( userID ) ;
345
+ const keys : string [ ] = [ ] ;
346
+
347
+ Object . keys ( tempData ) . forEach ( ( key : string ) => {
348
+ if ( key . startsWith ( PKCE_CODE_VERIFIER ) ) {
349
+ keys . push ( key ) ;
350
+ }
351
+ } ) ;
352
+
353
+ const lastKey : string | undefined = keys . sort ( ) . pop ( ) ;
354
+ const index : number = parseInt ( lastKey ?. split ( PKCE_SEPARATOR ) [ 1 ] ?? "-1" ) ;
355
+
356
+ return `${ PKCE_CODE_VERIFIER } ${ PKCE_SEPARATOR } ${ index + 1 } ` ;
357
+ }
332
358
}
0 commit comments