3
3
* Licensed under the MIT License.
4
4
*/
5
5
import {
6
- IAccount ,
7
6
SPAClient ,
8
7
INetworkModule ,
9
- TokenResponse ,
10
8
UrlString ,
11
- TokenRenewParameters ,
12
9
StringUtils ,
13
10
PromptValue ,
14
11
ServerError ,
@@ -24,9 +21,11 @@ import {
24
21
Constants ,
25
22
ClientAuthError ,
26
23
AuthorityType ,
24
+ CacheSchemaType ,
27
25
AuthenticationResult ,
28
26
SilentFlowRequest ,
29
- AccountEntity
27
+ AccountEntity ,
28
+ IAccount
30
29
} from "@azure/msal-common" ;
31
30
import { buildConfiguration , Configuration } from "../config/Configuration" ;
32
31
import { BrowserStorage } from "../cache/BrowserStorage" ;
@@ -65,6 +64,7 @@ export class PublicClientApplication {
65
64
// Input configuration by developer/user
66
65
private config : Configuration ;
67
66
67
+ // Default authority
68
68
protected defaultAuthorityInstance : Authority ;
69
69
70
70
/**
@@ -197,10 +197,10 @@ export class PublicClientApplication {
197
197
private async handleRedirectResponse ( ) : Promise < AuthenticationResult > {
198
198
// Get current location hash from window or cache.
199
199
const { location : { hash} } = window ;
200
- const cachedHash = this . browserStorage . getItem ( TemporaryCacheKeys . URL_HASH ) ;
200
+ const cachedHash = this . browserStorage . getItem ( this . browserStorage . generateCacheKey ( TemporaryCacheKeys . URL_HASH ) , CacheSchemaType . TEMPORARY ) as string ;
201
201
const isResponseHash = UrlString . hashContainsKnownProperties ( hash ) ;
202
202
203
- const loginRequestUrl = this . browserStorage . getItem ( TemporaryCacheKeys . ORIGIN_URI ) ;
203
+ const loginRequestUrl = this . browserStorage . getItem ( this . browserStorage . generateCacheKey ( TemporaryCacheKeys . ORIGIN_URI ) , CacheSchemaType . TEMPORARY ) as string ;
204
204
const currentUrl = BrowserUtils . getCurrentUri ( ) ;
205
205
if ( loginRequestUrl === currentUrl ) {
206
206
// We don't need to navigate - check for hash and prepare to process
@@ -215,7 +215,8 @@ export class PublicClientApplication {
215
215
216
216
if ( this . config . auth . navigateToLoginRequestUrl && isResponseHash && ! BrowserUtils . isInIframe ( ) ) {
217
217
// Returned from authority using redirect - need to perform navigation before processing response
218
- this . browserStorage . setItem ( TemporaryCacheKeys . URL_HASH , hash ) ;
218
+ const hashKey = this . browserStorage . generateCacheKey ( TemporaryCacheKeys . URL_HASH ) ;
219
+ this . browserStorage . setItem ( hashKey , hash , CacheSchemaType . TEMPORARY ) ;
219
220
220
221
if ( StringUtils . isEmpty ( loginRequestUrl ) || loginRequestUrl === "null" ) {
221
222
// Redirect to home page if login request url is null (real null or the string null)
@@ -262,15 +263,15 @@ export class PublicClientApplication {
262
263
/**
263
264
* Use when initiating the login process by redirecting the user's browser to the authorization endpoint. This function redirects the page, so
264
265
* any code that follows this function will not execute.
265
- *
266
+ *
266
267
* IMPORTANT: It is NOT recommended to have code that is dependent on the resolution of the Promise. This function will navigate away from the current
267
268
* browser window. It currently returns a Promise in order to reflect the asynchronous nature of the code running in this function.
268
- *
269
+ *
269
270
* @param {@link (AuthenticationParameters:type) }
270
271
*/
271
272
async loginRedirect ( request : AuthorizationUrlRequest ) : Promise < void > {
272
- // Preflight request
273
273
try {
274
+ // Preflight request
274
275
const validRequest : AuthorizationUrlRequest = this . preflightRequest ( request ) ;
275
276
276
277
// Create auth code request and generate PKCE params
@@ -289,11 +290,11 @@ export class PublicClientApplication {
289
290
throw e ;
290
291
}
291
292
}
292
-
293
+
293
294
/**
294
295
* Use when you want to obtain an access_token for your API by redirecting the user's browser window to the authorization endpoint. This function redirects
295
- * the page, so any code that follows this function will not execute.
296
- *
296
+ * the page, so any code that follows this function will not execute.
297
+ *
297
298
* IMPORTANT: It is NOT recommended to have code that is dependent on the resolution of the Promise. This function will navigate away from the current
298
299
* browser window. It currently returns a Promise in order to reflect the asynchronous nature of the code running in this function.
299
300
* @param {@link (AuthenticationParameters:type) }
@@ -454,18 +455,13 @@ export class PublicClientApplication {
454
455
* @param {@link AuthenticationParameters }
455
456
*
456
457
* To renew idToken, please pass clientId as the only scope in the Authentication Parameters
457
- * @returns {Promise.<TokenResponse > } - a promise that is fulfilled when this function has completed, or rejected if an error was raised. Returns the {@link AuthResponse} object
458
+ * @returns {Promise.<AuthenticationResult > } - a promise that is fulfilled when this function has completed, or rejected if an error was raised. Returns the {@link AuthResponse} object
458
459
*
459
460
*/
460
461
async acquireTokenSilent ( silentRequest : SilentFlowRequest ) : Promise < AuthenticationResult > {
461
462
// block the reload if it occurred inside a hidden iframe
462
463
BrowserUtils . blockReloadInHiddenIframes ( ) ;
463
464
464
- const tokenRequest : AuthorizationUrlRequest = {
465
- ...silentRequest ,
466
- redirectUri : "" ,
467
- } ;
468
-
469
465
try {
470
466
// Send request to renew token. Auth module will throw errors if token cannot be renewed.
471
467
return await this . authModule . getValidToken ( silentRequest ) ;
@@ -475,7 +471,8 @@ export class PublicClientApplication {
475
471
const isInvalidGrantError = ( e . errorCode === BrowserConstants . INVALID_GRANT_ERROR ) ;
476
472
if ( isServerError && isInvalidGrantError && ! isInteractionRequiredError ) {
477
473
const silentAuthUrlRequest : AuthorizationUrlRequest = this . initializeRequest ( {
478
- ...tokenRequest ,
474
+ ...silentRequest ,
475
+ redirectUri : "" ,
479
476
prompt : PromptValue . NONE
480
477
} ) ;
481
478
@@ -524,9 +521,13 @@ export class PublicClientApplication {
524
521
* Use to log out the current user, and redirect the user to the postLogoutRedirectUri.
525
522
* Default behaviour is to redirect the user to `window.location.href`.
526
523
*/
527
- logout ( accountObj : IAccount ) : void {
524
+ logout ( account : IAccount , authorityString ?: string ) : void {
525
+ const authorityObj = StringUtils . isEmpty ( authorityString ) ? this . defaultAuthorityInstance : AuthorityFactory . createInstance (
526
+ this . config . auth . authority ,
527
+ this . config . system . networkClient
528
+ ) ;
528
529
// create logout string and navigate user window to logout. Auth module will clear cache.
529
- this . authModule . logout ( accountObj , this . defaultAuthorityInstance ) . then ( ( logoutUri : string ) => {
530
+ this . authModule . logout ( account , authorityObj ) . then ( ( logoutUri : string ) => {
530
531
BrowserUtils . navigateWindow ( logoutUri ) ;
531
532
} ) ;
532
533
}
@@ -557,13 +558,24 @@ export class PublicClientApplication {
557
558
}
558
559
559
560
/**
560
- * Returns the signed in account
561
+ * Returns all accounts that MSAL currently has data for.
562
+ * (the account object is created at the time of successful login)
563
+ * or null when no state is found
564
+ * @returns {@link IAccount[] } - Array of account objects in cache
565
+ */
566
+ public getAllAccounts ( ) : IAccount [ ] {
567
+ return this . authModule . getAllAccounts ( ) ;
568
+ }
569
+
570
+ /**
571
+ * Returns the signed in account matching username.
561
572
* (the account object is created at the time of successful login)
562
573
* or null when no state is found
563
- * @returns {@link Account } - the account object stored in MSAL
574
+ * @returns {@link IAccount } - the account object stored in MSAL
564
575
*/
565
- public getAccount ( homeAccountId : string ) : AccountEntity {
566
- return this . authModule . getAccount ( homeAccountId ) ;
576
+ public getAccountByUsername ( userName : string ) : IAccount {
577
+ const allAccounts = this . getAllAccounts ( ) ;
578
+ return allAccounts . filter ( accountObj => accountObj . username === userName ) [ 0 ] ;
567
579
}
568
580
569
581
// #endregion
@@ -575,13 +587,13 @@ export class PublicClientApplication {
575
587
*/
576
588
private interactionInProgress ( ) : boolean {
577
589
// Check whether value in cache is present and equal to expected value
578
- return this . browserStorage . getItem ( BrowserConstants . INTERACTION_STATUS_KEY ) === BrowserConstants . INTERACTION_IN_PROGRESS_VALUE ;
590
+ return ( this . browserStorage . getItem ( this . browserStorage . generateCacheKey ( BrowserConstants . INTERACTION_STATUS_KEY ) , CacheSchemaType . TEMPORARY ) as string ) === BrowserConstants . INTERACTION_IN_PROGRESS_VALUE ;
579
591
}
580
592
581
593
/**
582
594
* Helper to validate app environment before making a request.
583
595
*/
584
- private preflightRequest ( request : AuthorizationUrlRequest ) : AuthorizationUrlRequest {
596
+ private preflightRequest ( request : AuthorizationUrlRequest ) : AuthorizationUrlRequest {
585
597
// block the reload if it occurred inside a hidden iframe
586
598
BrowserUtils . blockReloadInHiddenIframes ( ) ;
587
599
@@ -595,7 +607,7 @@ export class PublicClientApplication {
595
607
596
608
/**
597
609
* Helper to initialize required request parameters.
598
- * @param request
610
+ * @param request
599
611
*/
600
612
private initializeRequest ( request : AuthorizationUrlRequest ) : AuthorizationUrlRequest {
601
613
const validatedRequest : AuthorizationUrlRequest = {
@@ -605,7 +617,7 @@ export class PublicClientApplication {
605
617
// Check for ADAL SSO
606
618
if ( StringUtils . isEmpty ( validatedRequest . loginHint ) ) {
607
619
// Only check for adal token if no SSO params are being used
608
- const adalIdTokenString = this . browserStorage . getItem ( PersistentCacheKeys . ADAL_ID_TOKEN ) ;
620
+ const adalIdTokenString = this . browserStorage . getItem ( PersistentCacheKeys . ADAL_ID_TOKEN , CacheSchemaType . TEMPORARY ) as string ;
609
621
if ( ! StringUtils . isEmpty ( adalIdTokenString ) ) {
610
622
const adalIdToken = new IdToken ( adalIdTokenString , this . browserCrypto ) ;
611
623
this . browserStorage . removeItem ( PersistentCacheKeys . ADAL_ID_TOKEN ) ;
0 commit comments