@azure/msal-browser 3.11.1 → 3.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/IPublicClientApplication.mjs +1 -1
- package/dist/app/PublicClientApplication.mjs +1 -1
- package/dist/app/PublicClientNext.mjs +1 -1
- package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
- package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
- package/dist/cache/AsyncMemoryStorage.mjs +1 -1
- package/dist/cache/BrowserCacheManager.d.ts +10 -2
- package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
- package/dist/cache/BrowserCacheManager.mjs +31 -3
- package/dist/cache/BrowserCacheManager.mjs.map +1 -1
- package/dist/cache/BrowserStorage.mjs +1 -1
- package/dist/cache/DatabaseStorage.mjs +1 -1
- package/dist/cache/MemoryStorage.mjs +1 -1
- package/dist/cache/TokenCache.mjs +1 -1
- package/dist/config/Configuration.mjs +1 -1
- package/dist/controllers/ControllerFactory.mjs +1 -1
- package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/dist/controllers/NestedAppAuthController.mjs +3 -8
- package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
- package/dist/controllers/StandardController.d.ts +14 -0
- package/dist/controllers/StandardController.d.ts.map +1 -1
- package/dist/controllers/StandardController.mjs +162 -103
- package/dist/controllers/StandardController.mjs.map +1 -1
- package/dist/controllers/UnknownOperatingContextController.d.ts.map +1 -1
- package/dist/controllers/UnknownOperatingContextController.mjs +2 -2
- package/dist/controllers/UnknownOperatingContextController.mjs.map +1 -1
- package/dist/crypto/BrowserCrypto.mjs +1 -1
- package/dist/crypto/CryptoOps.mjs +1 -1
- package/dist/crypto/PkceGenerator.mjs +1 -1
- package/dist/crypto/SignedHttpRequest.mjs +1 -1
- package/dist/encode/Base64Decode.mjs +1 -1
- package/dist/encode/Base64Encode.mjs +1 -1
- package/dist/error/BrowserAuthError.mjs +1 -1
- package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
- package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
- package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
- package/dist/error/NativeAuthError.mjs +1 -1
- package/dist/error/NativeAuthErrorCodes.mjs +1 -1
- package/dist/error/NestedAppAuthError.mjs +1 -1
- package/dist/event/EventHandler.mjs +1 -1
- package/dist/event/EventMessage.mjs +1 -1
- package/dist/event/EventType.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
- package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
- package/dist/interaction_client/NativeInteractionClient.mjs +1 -1
- package/dist/interaction_client/PopupClient.mjs +1 -1
- package/dist/interaction_client/RedirectClient.mjs +1 -1
- package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
- package/dist/interaction_client/SilentCacheClient.mjs +1 -1
- package/dist/interaction_client/SilentIframeClient.mjs +1 -1
- package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
- package/dist/interaction_client/StandardInteractionClient.mjs +1 -1
- package/dist/interaction_handler/InteractionHandler.mjs +1 -1
- package/dist/interaction_handler/RedirectHandler.mjs +1 -1
- package/dist/interaction_handler/SilentHandler.mjs +2 -1
- package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
- package/dist/naa/BridgeError.mjs +1 -1
- package/dist/naa/BridgeProxy.d.ts +0 -2
- package/dist/naa/BridgeProxy.d.ts.map +1 -1
- package/dist/naa/BridgeProxy.mjs +4 -10
- package/dist/naa/BridgeProxy.mjs.map +1 -1
- package/dist/naa/BridgeStatusCode.mjs +1 -1
- package/dist/naa/mapping/NestedAppAuthAdapter.mjs +1 -1
- package/dist/navigation/NavigationClient.mjs +1 -1
- package/dist/network/FetchClient.mjs +1 -1
- package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
- package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
- package/dist/operatingcontext/TeamsAppOperatingContext.mjs +1 -1
- package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
- package/dist/packageMetadata.d.ts +1 -1
- package/dist/packageMetadata.mjs +2 -2
- package/dist/request/RequestHelpers.mjs +1 -1
- package/dist/response/ResponseHandler.mjs +1 -1
- package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
- package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
- package/dist/utils/BrowserConstants.mjs +1 -1
- package/dist/utils/BrowserProtocolUtils.mjs +1 -1
- package/dist/utils/BrowserUtils.mjs +1 -1
- package/lib/msal-browser.cjs +363 -206
- package/lib/msal-browser.cjs.map +1 -1
- package/lib/msal-browser.js +363 -206
- package/lib/msal-browser.js.map +1 -1
- package/lib/msal-browser.min.js +67 -66
- package/package.json +4 -4
- package/src/cache/BrowserCacheManager.ts +49 -1
- package/src/controllers/NestedAppAuthController.ts +7 -6
- package/src/controllers/StandardController.ts +329 -246
- package/src/controllers/UnknownOperatingContextController.ts +3 -1
- package/src/interaction_handler/SilentHandler.ts +1 -0
- package/src/naa/BridgeProxy.ts +3 -12
- package/src/packageMetadata.ts +1 -1
|
@@ -141,6 +141,9 @@ export class StandardController implements IController {
|
|
|
141
141
|
Promise<AuthenticationResult>
|
|
142
142
|
>;
|
|
143
143
|
|
|
144
|
+
// Active Iframe request
|
|
145
|
+
private activeIframeRequest: [Promise<void>, string] | undefined;
|
|
146
|
+
|
|
144
147
|
private ssoSilentMeasurement?: InProgressPerformanceEvent;
|
|
145
148
|
private acquireTokenByCodeAsyncMeasurement?: InProgressPerformanceEvent;
|
|
146
149
|
/**
|
|
@@ -204,7 +207,8 @@ export class StandardController implements IController {
|
|
|
204
207
|
this.config.cache,
|
|
205
208
|
this.browserCrypto,
|
|
206
209
|
this.logger,
|
|
207
|
-
buildStaticAuthorityOptions(this.config.auth)
|
|
210
|
+
buildStaticAuthorityOptions(this.config.auth),
|
|
211
|
+
this.performanceClient
|
|
208
212
|
)
|
|
209
213
|
: DEFAULT_BROWSER_CACHE_MANAGER(
|
|
210
214
|
this.config.auth.clientId,
|
|
@@ -224,7 +228,9 @@ export class StandardController implements IController {
|
|
|
224
228
|
this.config.auth.clientId,
|
|
225
229
|
nativeCacheOptions,
|
|
226
230
|
this.browserCrypto,
|
|
227
|
-
this.logger
|
|
231
|
+
this.logger,
|
|
232
|
+
undefined,
|
|
233
|
+
this.performanceClient
|
|
228
234
|
);
|
|
229
235
|
|
|
230
236
|
// Initialize the token cache
|
|
@@ -332,7 +338,6 @@ export class StandardController implements IController {
|
|
|
332
338
|
// Block token acquisition before initialize has been called
|
|
333
339
|
BrowserUtils.blockAPICallsBeforeInitialize(this.initialized);
|
|
334
340
|
|
|
335
|
-
const loggedInAccounts = this.getAllAccounts();
|
|
336
341
|
if (this.isBrowserEnvironment) {
|
|
337
342
|
/**
|
|
338
343
|
* Store the promise on the PublicClientApplication instance if this is the first invocation of handleRedirectPromise,
|
|
@@ -342,155 +347,11 @@ export class StandardController implements IController {
|
|
|
342
347
|
const redirectResponseKey = hash || "";
|
|
343
348
|
let response = this.redirectResponse.get(redirectResponseKey);
|
|
344
349
|
if (typeof response === "undefined") {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
const useNative =
|
|
348
|
-
request &&
|
|
349
|
-
NativeMessageHandler.isNativeAvailable(
|
|
350
|
-
this.config,
|
|
351
|
-
this.logger,
|
|
352
|
-
this.nativeExtensionProvider
|
|
353
|
-
) &&
|
|
354
|
-
this.nativeExtensionProvider &&
|
|
355
|
-
!hash;
|
|
356
|
-
const correlationId = useNative
|
|
357
|
-
? request?.correlationId
|
|
358
|
-
: this.browserStorage.getTemporaryCache(
|
|
359
|
-
TemporaryCacheKeys.CORRELATION_ID,
|
|
360
|
-
true
|
|
361
|
-
) || "";
|
|
362
|
-
const rootMeasurement = this.performanceClient.startMeasurement(
|
|
363
|
-
"acquireTokenRedirect",
|
|
364
|
-
correlationId
|
|
365
|
-
);
|
|
366
|
-
this.eventHandler.emitEvent(
|
|
367
|
-
EventType.HANDLE_REDIRECT_START,
|
|
368
|
-
InteractionType.Redirect
|
|
369
|
-
);
|
|
350
|
+
response = this.handleRedirectPromiseInternal(hash);
|
|
351
|
+
this.redirectResponse.set(redirectResponseKey, response);
|
|
370
352
|
this.logger.verbose(
|
|
371
353
|
"handleRedirectPromise has been called for the first time, storing the promise"
|
|
372
354
|
);
|
|
373
|
-
let redirectResponse: Promise<AuthenticationResult | null>;
|
|
374
|
-
if (useNative && this.nativeExtensionProvider) {
|
|
375
|
-
this.logger.trace(
|
|
376
|
-
"handleRedirectPromise - acquiring token from native platform"
|
|
377
|
-
);
|
|
378
|
-
const nativeClient = new NativeInteractionClient(
|
|
379
|
-
this.config,
|
|
380
|
-
this.browserStorage,
|
|
381
|
-
this.browserCrypto,
|
|
382
|
-
this.logger,
|
|
383
|
-
this.eventHandler,
|
|
384
|
-
this.navigationClient,
|
|
385
|
-
ApiId.handleRedirectPromise,
|
|
386
|
-
this.performanceClient,
|
|
387
|
-
this.nativeExtensionProvider,
|
|
388
|
-
request.accountId,
|
|
389
|
-
this.nativeInternalStorage,
|
|
390
|
-
request.correlationId
|
|
391
|
-
);
|
|
392
|
-
|
|
393
|
-
redirectResponse = invokeAsync(
|
|
394
|
-
nativeClient.handleRedirectPromise.bind(nativeClient),
|
|
395
|
-
PerformanceEvents.HandleNativeRedirectPromiseMeasurement,
|
|
396
|
-
this.logger,
|
|
397
|
-
this.performanceClient,
|
|
398
|
-
rootMeasurement.event.correlationId
|
|
399
|
-
)(
|
|
400
|
-
this.performanceClient,
|
|
401
|
-
rootMeasurement.event.correlationId
|
|
402
|
-
);
|
|
403
|
-
} else {
|
|
404
|
-
this.logger.trace(
|
|
405
|
-
"handleRedirectPromise - acquiring token from web flow"
|
|
406
|
-
);
|
|
407
|
-
const redirectClient =
|
|
408
|
-
this.createRedirectClient(correlationId);
|
|
409
|
-
redirectResponse = invokeAsync(
|
|
410
|
-
redirectClient.handleRedirectPromise.bind(
|
|
411
|
-
redirectClient
|
|
412
|
-
),
|
|
413
|
-
PerformanceEvents.HandleRedirectPromiseMeasurement,
|
|
414
|
-
this.logger,
|
|
415
|
-
this.performanceClient,
|
|
416
|
-
rootMeasurement.event.correlationId
|
|
417
|
-
)(
|
|
418
|
-
hash,
|
|
419
|
-
this.performanceClient,
|
|
420
|
-
rootMeasurement.event.correlationId
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
response = redirectResponse
|
|
425
|
-
.then((result: AuthenticationResult | null) => {
|
|
426
|
-
if (result) {
|
|
427
|
-
// Emit login event if number of accounts change
|
|
428
|
-
|
|
429
|
-
const isLoggingIn =
|
|
430
|
-
loggedInAccounts.length <
|
|
431
|
-
this.getAllAccounts().length;
|
|
432
|
-
if (isLoggingIn) {
|
|
433
|
-
this.eventHandler.emitEvent(
|
|
434
|
-
EventType.LOGIN_SUCCESS,
|
|
435
|
-
InteractionType.Redirect,
|
|
436
|
-
result
|
|
437
|
-
);
|
|
438
|
-
this.logger.verbose(
|
|
439
|
-
"handleRedirectResponse returned result, login success"
|
|
440
|
-
);
|
|
441
|
-
} else {
|
|
442
|
-
this.eventHandler.emitEvent(
|
|
443
|
-
EventType.ACQUIRE_TOKEN_SUCCESS,
|
|
444
|
-
InteractionType.Redirect,
|
|
445
|
-
result
|
|
446
|
-
);
|
|
447
|
-
this.logger.verbose(
|
|
448
|
-
"handleRedirectResponse returned result, acquire token success"
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
rootMeasurement.end({ success: true });
|
|
452
|
-
}
|
|
453
|
-
this.eventHandler.emitEvent(
|
|
454
|
-
EventType.HANDLE_REDIRECT_END,
|
|
455
|
-
InteractionType.Redirect
|
|
456
|
-
);
|
|
457
|
-
rootMeasurement.end({ success: false });
|
|
458
|
-
|
|
459
|
-
return result;
|
|
460
|
-
})
|
|
461
|
-
.catch((e) => {
|
|
462
|
-
const eventError = e as EventError;
|
|
463
|
-
// Emit login event if there is an account
|
|
464
|
-
if (loggedInAccounts.length > 0) {
|
|
465
|
-
this.eventHandler.emitEvent(
|
|
466
|
-
EventType.ACQUIRE_TOKEN_FAILURE,
|
|
467
|
-
InteractionType.Redirect,
|
|
468
|
-
null,
|
|
469
|
-
eventError
|
|
470
|
-
);
|
|
471
|
-
} else {
|
|
472
|
-
this.eventHandler.emitEvent(
|
|
473
|
-
EventType.LOGIN_FAILURE,
|
|
474
|
-
InteractionType.Redirect,
|
|
475
|
-
null,
|
|
476
|
-
eventError
|
|
477
|
-
);
|
|
478
|
-
}
|
|
479
|
-
this.eventHandler.emitEvent(
|
|
480
|
-
EventType.HANDLE_REDIRECT_END,
|
|
481
|
-
InteractionType.Redirect
|
|
482
|
-
);
|
|
483
|
-
|
|
484
|
-
rootMeasurement.end(
|
|
485
|
-
{
|
|
486
|
-
success: false,
|
|
487
|
-
},
|
|
488
|
-
eventError
|
|
489
|
-
);
|
|
490
|
-
|
|
491
|
-
throw e;
|
|
492
|
-
});
|
|
493
|
-
this.redirectResponse.set(redirectResponseKey, response);
|
|
494
355
|
} else {
|
|
495
356
|
this.logger.verbose(
|
|
496
357
|
"handleRedirectPromise has been called previously, returning the result from the first call"
|
|
@@ -505,6 +366,156 @@ export class StandardController implements IController {
|
|
|
505
366
|
return null;
|
|
506
367
|
}
|
|
507
368
|
|
|
369
|
+
/**
|
|
370
|
+
* The internal details of handleRedirectPromise. This is separated out to a helper to allow handleRedirectPromise to memoize requests
|
|
371
|
+
* @param hash
|
|
372
|
+
* @returns
|
|
373
|
+
*/
|
|
374
|
+
private async handleRedirectPromiseInternal(
|
|
375
|
+
hash?: string
|
|
376
|
+
): Promise<AuthenticationResult | null> {
|
|
377
|
+
const loggedInAccounts = this.getAllAccounts();
|
|
378
|
+
const request: NativeTokenRequest | null =
|
|
379
|
+
this.browserStorage.getCachedNativeRequest();
|
|
380
|
+
const useNative =
|
|
381
|
+
request &&
|
|
382
|
+
NativeMessageHandler.isNativeAvailable(
|
|
383
|
+
this.config,
|
|
384
|
+
this.logger,
|
|
385
|
+
this.nativeExtensionProvider
|
|
386
|
+
) &&
|
|
387
|
+
this.nativeExtensionProvider &&
|
|
388
|
+
!hash;
|
|
389
|
+
const correlationId = useNative
|
|
390
|
+
? request?.correlationId
|
|
391
|
+
: this.browserStorage.getTemporaryCache(
|
|
392
|
+
TemporaryCacheKeys.CORRELATION_ID,
|
|
393
|
+
true
|
|
394
|
+
) || "";
|
|
395
|
+
const rootMeasurement = this.performanceClient.startMeasurement(
|
|
396
|
+
"acquireTokenRedirect",
|
|
397
|
+
correlationId
|
|
398
|
+
);
|
|
399
|
+
this.eventHandler.emitEvent(
|
|
400
|
+
EventType.HANDLE_REDIRECT_START,
|
|
401
|
+
InteractionType.Redirect
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
let redirectResponse: Promise<AuthenticationResult | null>;
|
|
405
|
+
if (useNative && this.nativeExtensionProvider) {
|
|
406
|
+
this.logger.trace(
|
|
407
|
+
"handleRedirectPromise - acquiring token from native platform"
|
|
408
|
+
);
|
|
409
|
+
const nativeClient = new NativeInteractionClient(
|
|
410
|
+
this.config,
|
|
411
|
+
this.browserStorage,
|
|
412
|
+
this.browserCrypto,
|
|
413
|
+
this.logger,
|
|
414
|
+
this.eventHandler,
|
|
415
|
+
this.navigationClient,
|
|
416
|
+
ApiId.handleRedirectPromise,
|
|
417
|
+
this.performanceClient,
|
|
418
|
+
this.nativeExtensionProvider,
|
|
419
|
+
request.accountId,
|
|
420
|
+
this.nativeInternalStorage,
|
|
421
|
+
request.correlationId
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
redirectResponse = invokeAsync(
|
|
425
|
+
nativeClient.handleRedirectPromise.bind(nativeClient),
|
|
426
|
+
PerformanceEvents.HandleNativeRedirectPromiseMeasurement,
|
|
427
|
+
this.logger,
|
|
428
|
+
this.performanceClient,
|
|
429
|
+
rootMeasurement.event.correlationId
|
|
430
|
+
)(this.performanceClient, rootMeasurement.event.correlationId);
|
|
431
|
+
} else {
|
|
432
|
+
this.logger.trace(
|
|
433
|
+
"handleRedirectPromise - acquiring token from web flow"
|
|
434
|
+
);
|
|
435
|
+
const redirectClient = this.createRedirectClient(correlationId);
|
|
436
|
+
redirectResponse = invokeAsync(
|
|
437
|
+
redirectClient.handleRedirectPromise.bind(redirectClient),
|
|
438
|
+
PerformanceEvents.HandleRedirectPromiseMeasurement,
|
|
439
|
+
this.logger,
|
|
440
|
+
this.performanceClient,
|
|
441
|
+
rootMeasurement.event.correlationId
|
|
442
|
+
)(
|
|
443
|
+
hash,
|
|
444
|
+
this.performanceClient,
|
|
445
|
+
rootMeasurement.event.correlationId
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return redirectResponse
|
|
450
|
+
.then((result: AuthenticationResult | null) => {
|
|
451
|
+
if (result) {
|
|
452
|
+
// Emit login event if number of accounts change
|
|
453
|
+
|
|
454
|
+
const isLoggingIn =
|
|
455
|
+
loggedInAccounts.length < this.getAllAccounts().length;
|
|
456
|
+
if (isLoggingIn) {
|
|
457
|
+
this.eventHandler.emitEvent(
|
|
458
|
+
EventType.LOGIN_SUCCESS,
|
|
459
|
+
InteractionType.Redirect,
|
|
460
|
+
result
|
|
461
|
+
);
|
|
462
|
+
this.logger.verbose(
|
|
463
|
+
"handleRedirectResponse returned result, login success"
|
|
464
|
+
);
|
|
465
|
+
} else {
|
|
466
|
+
this.eventHandler.emitEvent(
|
|
467
|
+
EventType.ACQUIRE_TOKEN_SUCCESS,
|
|
468
|
+
InteractionType.Redirect,
|
|
469
|
+
result
|
|
470
|
+
);
|
|
471
|
+
this.logger.verbose(
|
|
472
|
+
"handleRedirectResponse returned result, acquire token success"
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
rootMeasurement.end({ success: true });
|
|
476
|
+
}
|
|
477
|
+
this.eventHandler.emitEvent(
|
|
478
|
+
EventType.HANDLE_REDIRECT_END,
|
|
479
|
+
InteractionType.Redirect
|
|
480
|
+
);
|
|
481
|
+
rootMeasurement.end({ success: false });
|
|
482
|
+
|
|
483
|
+
return result;
|
|
484
|
+
})
|
|
485
|
+
.catch((e) => {
|
|
486
|
+
const eventError = e as EventError;
|
|
487
|
+
// Emit login event if there is an account
|
|
488
|
+
if (loggedInAccounts.length > 0) {
|
|
489
|
+
this.eventHandler.emitEvent(
|
|
490
|
+
EventType.ACQUIRE_TOKEN_FAILURE,
|
|
491
|
+
InteractionType.Redirect,
|
|
492
|
+
null,
|
|
493
|
+
eventError
|
|
494
|
+
);
|
|
495
|
+
} else {
|
|
496
|
+
this.eventHandler.emitEvent(
|
|
497
|
+
EventType.LOGIN_FAILURE,
|
|
498
|
+
InteractionType.Redirect,
|
|
499
|
+
null,
|
|
500
|
+
eventError
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
this.eventHandler.emitEvent(
|
|
504
|
+
EventType.HANDLE_REDIRECT_END,
|
|
505
|
+
InteractionType.Redirect
|
|
506
|
+
);
|
|
507
|
+
|
|
508
|
+
rootMeasurement.end(
|
|
509
|
+
{
|
|
510
|
+
success: false,
|
|
511
|
+
},
|
|
512
|
+
eventError
|
|
513
|
+
);
|
|
514
|
+
|
|
515
|
+
throw e;
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
|
|
508
519
|
/**
|
|
509
520
|
* 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
|
|
510
521
|
* the page, so any code that follows this function will not execute.
|
|
@@ -1966,24 +1977,180 @@ export class StandardController implements IController {
|
|
|
1966
1977
|
document.addEventListener("visibilitychange", () =>
|
|
1967
1978
|
this.trackPageVisibility(request.correlationId)
|
|
1968
1979
|
);
|
|
1969
|
-
|
|
1980
|
+
|
|
1981
|
+
const silentRequest = await invokeAsync(
|
|
1982
|
+
initializeSilentRequest,
|
|
1983
|
+
PerformanceEvents.InitializeSilentRequest,
|
|
1984
|
+
this.logger,
|
|
1985
|
+
this.performanceClient,
|
|
1986
|
+
request.correlationId
|
|
1987
|
+
)(request, account, this.config, this.performanceClient, this.logger);
|
|
1988
|
+
const cacheLookupPolicy =
|
|
1989
|
+
request.cacheLookupPolicy || CacheLookupPolicy.Default;
|
|
1990
|
+
|
|
1991
|
+
const result = this.acquireTokenSilentNoIframe(
|
|
1992
|
+
silentRequest,
|
|
1993
|
+
cacheLookupPolicy
|
|
1994
|
+
).catch(async (refreshTokenError: AuthError) => {
|
|
1995
|
+
const shouldTryToResolveSilently =
|
|
1996
|
+
checkIfRefreshTokenErrorCanBeResolvedSilently(
|
|
1997
|
+
refreshTokenError,
|
|
1998
|
+
cacheLookupPolicy
|
|
1999
|
+
);
|
|
2000
|
+
|
|
2001
|
+
if (shouldTryToResolveSilently) {
|
|
2002
|
+
if (!this.activeIframeRequest) {
|
|
2003
|
+
let _resolve: () => void,
|
|
2004
|
+
_reject: (reason?: AuthError | Error) => void;
|
|
2005
|
+
// Always set the active request tracker immediately after checking it to prevent races
|
|
2006
|
+
this.activeIframeRequest = [
|
|
2007
|
+
new Promise((resolve, reject) => {
|
|
2008
|
+
_resolve = resolve;
|
|
2009
|
+
_reject = reject;
|
|
2010
|
+
}),
|
|
2011
|
+
silentRequest.correlationId,
|
|
2012
|
+
];
|
|
2013
|
+
this.logger.verbose(
|
|
2014
|
+
"Refresh token expired/invalid or CacheLookupPolicy is set to Skip, attempting acquire token by iframe.",
|
|
2015
|
+
silentRequest.correlationId
|
|
2016
|
+
);
|
|
2017
|
+
return invokeAsync(
|
|
2018
|
+
this.acquireTokenBySilentIframe.bind(this),
|
|
2019
|
+
PerformanceEvents.AcquireTokenBySilentIframe,
|
|
2020
|
+
this.logger,
|
|
2021
|
+
this.performanceClient,
|
|
2022
|
+
silentRequest.correlationId
|
|
2023
|
+
)(silentRequest)
|
|
2024
|
+
.then((iframeResult) => {
|
|
2025
|
+
_resolve();
|
|
2026
|
+
return iframeResult;
|
|
2027
|
+
})
|
|
2028
|
+
.catch((e) => {
|
|
2029
|
+
_reject(e);
|
|
2030
|
+
throw e;
|
|
2031
|
+
})
|
|
2032
|
+
.finally(() => {
|
|
2033
|
+
this.activeIframeRequest = undefined;
|
|
2034
|
+
});
|
|
2035
|
+
} else if (cacheLookupPolicy !== CacheLookupPolicy.Skip) {
|
|
2036
|
+
const [activePromise, activeCorrelationId] =
|
|
2037
|
+
this.activeIframeRequest;
|
|
2038
|
+
this.logger.verbose(
|
|
2039
|
+
`Iframe request is already in progress, awaiting resolution for request with correlationId: ${activeCorrelationId}`,
|
|
2040
|
+
silentRequest.correlationId
|
|
2041
|
+
);
|
|
2042
|
+
const awaitConcurrentIframeMeasure =
|
|
2043
|
+
this.performanceClient.startMeasurement(
|
|
2044
|
+
PerformanceEvents.AwaitConcurrentIframe,
|
|
2045
|
+
silentRequest.correlationId
|
|
2046
|
+
);
|
|
2047
|
+
awaitConcurrentIframeMeasure.add({
|
|
2048
|
+
awaitIframeCorrelationId: activeCorrelationId,
|
|
2049
|
+
});
|
|
2050
|
+
|
|
2051
|
+
// Await for errors first so we can distinguish errors thrown by activePromise versus errors thrown by .then below
|
|
2052
|
+
await activePromise.catch(() => {
|
|
2053
|
+
awaitConcurrentIframeMeasure.end({
|
|
2054
|
+
success: false,
|
|
2055
|
+
});
|
|
2056
|
+
this.logger.info(
|
|
2057
|
+
`Iframe request with correlationId: ${activeCorrelationId} failed. Interaction is required.`
|
|
2058
|
+
);
|
|
2059
|
+
// If previous iframe request failed, it's unlikely to succeed this time. Throw original error.
|
|
2060
|
+
throw refreshTokenError;
|
|
2061
|
+
});
|
|
2062
|
+
|
|
2063
|
+
return activePromise.then(() => {
|
|
2064
|
+
awaitConcurrentIframeMeasure.end({ success: true });
|
|
2065
|
+
this.logger.verbose(
|
|
2066
|
+
`Parallel iframe request with correlationId: ${activeCorrelationId} succeeded. Retrying cache and/or RT redemption`,
|
|
2067
|
+
silentRequest.correlationId
|
|
2068
|
+
);
|
|
2069
|
+
// Retry cache lookup and/or RT exchange after iframe completes
|
|
2070
|
+
return this.acquireTokenSilentNoIframe(
|
|
2071
|
+
silentRequest,
|
|
2072
|
+
cacheLookupPolicy
|
|
2073
|
+
);
|
|
2074
|
+
});
|
|
2075
|
+
} else {
|
|
2076
|
+
// Cache policy set to skip and another iframe request is already in progress
|
|
2077
|
+
this.logger.warning(
|
|
2078
|
+
"Another iframe request is currently in progress and CacheLookupPolicy is set to Skip. This may result in degraded performance and/or reliability for both calls. Please consider changing the CacheLookupPolicy to take advantage of request queuing and token cache.",
|
|
2079
|
+
silentRequest.correlationId
|
|
2080
|
+
);
|
|
2081
|
+
return invokeAsync(
|
|
2082
|
+
this.acquireTokenBySilentIframe.bind(this),
|
|
2083
|
+
PerformanceEvents.AcquireTokenBySilentIframe,
|
|
2084
|
+
this.logger,
|
|
2085
|
+
this.performanceClient,
|
|
2086
|
+
silentRequest.correlationId
|
|
2087
|
+
)(silentRequest);
|
|
2088
|
+
}
|
|
2089
|
+
} else {
|
|
2090
|
+
// Error cannot be silently resolved or iframe renewal is not allowed, interaction required
|
|
2091
|
+
throw refreshTokenError;
|
|
2092
|
+
}
|
|
2093
|
+
});
|
|
2094
|
+
|
|
2095
|
+
return result
|
|
2096
|
+
.then((response) => {
|
|
2097
|
+
this.eventHandler.emitEvent(
|
|
2098
|
+
EventType.ACQUIRE_TOKEN_SUCCESS,
|
|
2099
|
+
InteractionType.Silent,
|
|
2100
|
+
response
|
|
2101
|
+
);
|
|
2102
|
+
if (request.correlationId) {
|
|
2103
|
+
this.performanceClient.addFields(
|
|
2104
|
+
{
|
|
2105
|
+
fromCache: response.fromCache,
|
|
2106
|
+
isNativeBroker: response.fromNativeBroker,
|
|
2107
|
+
requestId: response.requestId,
|
|
2108
|
+
},
|
|
2109
|
+
request.correlationId
|
|
2110
|
+
);
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
return response;
|
|
2114
|
+
})
|
|
2115
|
+
.catch((tokenRenewalError: Error) => {
|
|
2116
|
+
this.eventHandler.emitEvent(
|
|
2117
|
+
EventType.ACQUIRE_TOKEN_FAILURE,
|
|
2118
|
+
InteractionType.Silent,
|
|
2119
|
+
null,
|
|
2120
|
+
tokenRenewalError
|
|
2121
|
+
);
|
|
2122
|
+
throw tokenRenewalError;
|
|
2123
|
+
})
|
|
2124
|
+
.finally(() => {
|
|
2125
|
+
document.removeEventListener("visibilitychange", () =>
|
|
2126
|
+
this.trackPageVisibility(request.correlationId)
|
|
2127
|
+
);
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
/**
|
|
2132
|
+
* AcquireTokenSilent without the iframe fallback. This is used to enable the correct fallbacks in cases where there's a potential for multiple silent requests to be made in parallel and prevent those requests from making concurrent iframe requests.
|
|
2133
|
+
* @param silentRequest
|
|
2134
|
+
* @param cacheLookupPolicy
|
|
2135
|
+
* @returns
|
|
2136
|
+
*/
|
|
2137
|
+
private async acquireTokenSilentNoIframe(
|
|
2138
|
+
silentRequest: CommonSilentFlowRequest,
|
|
2139
|
+
cacheLookupPolicy: CacheLookupPolicy
|
|
2140
|
+
): Promise<AuthenticationResult> {
|
|
1970
2141
|
if (
|
|
1971
2142
|
NativeMessageHandler.isNativeAvailable(
|
|
1972
2143
|
this.config,
|
|
1973
2144
|
this.logger,
|
|
1974
2145
|
this.nativeExtensionProvider,
|
|
1975
|
-
|
|
2146
|
+
silentRequest.authenticationScheme
|
|
1976
2147
|
) &&
|
|
1977
|
-
account.nativeAccountId
|
|
2148
|
+
silentRequest.account.nativeAccountId
|
|
1978
2149
|
) {
|
|
1979
2150
|
this.logger.verbose(
|
|
1980
2151
|
"acquireTokenSilent - attempting to acquire token from native platform"
|
|
1981
2152
|
);
|
|
1982
|
-
|
|
1983
|
-
...request,
|
|
1984
|
-
account,
|
|
1985
|
-
};
|
|
1986
|
-
result = this.acquireTokenNative(
|
|
2153
|
+
return this.acquireTokenNative(
|
|
1987
2154
|
silentRequest,
|
|
1988
2155
|
ApiId.acquireTokenSilent_silentFlow
|
|
1989
2156
|
).catch(async (e: AuthError) => {
|
|
@@ -1995,10 +2162,9 @@ export class StandardController implements IController {
|
|
|
1995
2162
|
this.nativeExtensionProvider = undefined; // Prevent future requests from continuing to attempt
|
|
1996
2163
|
|
|
1997
2164
|
// Cache will not contain tokens, given that previous WAM requests succeeded. Skip cache and RT renewal and go straight to iframe renewal
|
|
1998
|
-
|
|
1999
|
-
|
|
2165
|
+
throw createClientAuthError(
|
|
2166
|
+
ClientAuthErrorCodes.tokenRefreshRequired
|
|
2000
2167
|
);
|
|
2001
|
-
return silentIframeClient.acquireToken(request);
|
|
2002
2168
|
}
|
|
2003
2169
|
throw e;
|
|
2004
2170
|
});
|
|
@@ -2006,25 +2172,7 @@ export class StandardController implements IController {
|
|
|
2006
2172
|
this.logger.verbose(
|
|
2007
2173
|
"acquireTokenSilent - attempting to acquire token from web flow"
|
|
2008
2174
|
);
|
|
2009
|
-
|
|
2010
|
-
const silentRequest = await invokeAsync(
|
|
2011
|
-
initializeSilentRequest,
|
|
2012
|
-
PerformanceEvents.InitializeSilentRequest,
|
|
2013
|
-
this.logger,
|
|
2014
|
-
this.performanceClient,
|
|
2015
|
-
request.correlationId
|
|
2016
|
-
)(
|
|
2017
|
-
request,
|
|
2018
|
-
account,
|
|
2019
|
-
this.config,
|
|
2020
|
-
this.performanceClient,
|
|
2021
|
-
this.logger
|
|
2022
|
-
);
|
|
2023
|
-
|
|
2024
|
-
const cacheLookupPolicy =
|
|
2025
|
-
request.cacheLookupPolicy || CacheLookupPolicy.Default;
|
|
2026
|
-
|
|
2027
|
-
result = invokeAsync(
|
|
2175
|
+
return invokeAsync(
|
|
2028
2176
|
this.acquireTokenFromCache.bind(this),
|
|
2029
2177
|
PerformanceEvents.AcquireTokenFromCache,
|
|
2030
2178
|
this.logger,
|
|
@@ -2032,10 +2180,7 @@ export class StandardController implements IController {
|
|
|
2032
2180
|
silentRequest.correlationId
|
|
2033
2181
|
)(silentRequest, cacheLookupPolicy).catch(
|
|
2034
2182
|
(cacheError: AuthError) => {
|
|
2035
|
-
if (
|
|
2036
|
-
request.cacheLookupPolicy ===
|
|
2037
|
-
CacheLookupPolicy.AccessToken
|
|
2038
|
-
) {
|
|
2183
|
+
if (cacheLookupPolicy === CacheLookupPolicy.AccessToken) {
|
|
2039
2184
|
throw cacheError;
|
|
2040
2185
|
}
|
|
2041
2186
|
|
|
@@ -2051,71 +2196,10 @@ export class StandardController implements IController {
|
|
|
2051
2196
|
this.logger,
|
|
2052
2197
|
this.performanceClient,
|
|
2053
2198
|
silentRequest.correlationId
|
|
2054
|
-
)(silentRequest, cacheLookupPolicy)
|
|
2055
|
-
(refreshTokenError: AuthError) => {
|
|
2056
|
-
const shouldTryToResolveSilently =
|
|
2057
|
-
checkIfRefreshTokenErrorCanBeResolvedSilently(
|
|
2058
|
-
refreshTokenError,
|
|
2059
|
-
silentRequest,
|
|
2060
|
-
cacheLookupPolicy
|
|
2061
|
-
);
|
|
2062
|
-
|
|
2063
|
-
if (shouldTryToResolveSilently) {
|
|
2064
|
-
this.logger.verbose(
|
|
2065
|
-
"Refresh token expired/invalid or CacheLookupPolicy is set to Skip, attempting acquire token by iframe.",
|
|
2066
|
-
silentRequest.correlationId
|
|
2067
|
-
);
|
|
2068
|
-
return invokeAsync(
|
|
2069
|
-
this.acquireTokenBySilentIframe.bind(this),
|
|
2070
|
-
PerformanceEvents.AcquireTokenBySilentIframe,
|
|
2071
|
-
this.logger,
|
|
2072
|
-
this.performanceClient,
|
|
2073
|
-
silentRequest.correlationId
|
|
2074
|
-
)(silentRequest);
|
|
2075
|
-
} else {
|
|
2076
|
-
// Error cannot be silently resolved or iframe renewal is not allowed, interaction required
|
|
2077
|
-
throw refreshTokenError;
|
|
2078
|
-
}
|
|
2079
|
-
}
|
|
2080
|
-
);
|
|
2199
|
+
)(silentRequest, cacheLookupPolicy);
|
|
2081
2200
|
}
|
|
2082
2201
|
);
|
|
2083
2202
|
}
|
|
2084
|
-
|
|
2085
|
-
return result
|
|
2086
|
-
.then((response) => {
|
|
2087
|
-
this.eventHandler.emitEvent(
|
|
2088
|
-
EventType.ACQUIRE_TOKEN_SUCCESS,
|
|
2089
|
-
InteractionType.Silent,
|
|
2090
|
-
response
|
|
2091
|
-
);
|
|
2092
|
-
if (request.correlationId) {
|
|
2093
|
-
this.performanceClient.addFields(
|
|
2094
|
-
{
|
|
2095
|
-
fromCache: response.fromCache,
|
|
2096
|
-
isNativeBroker: response.fromNativeBroker,
|
|
2097
|
-
requestId: response.requestId,
|
|
2098
|
-
},
|
|
2099
|
-
request.correlationId
|
|
2100
|
-
);
|
|
2101
|
-
}
|
|
2102
|
-
|
|
2103
|
-
return response;
|
|
2104
|
-
})
|
|
2105
|
-
.catch((tokenRenewalError: Error) => {
|
|
2106
|
-
this.eventHandler.emitEvent(
|
|
2107
|
-
EventType.ACQUIRE_TOKEN_FAILURE,
|
|
2108
|
-
InteractionType.Silent,
|
|
2109
|
-
null,
|
|
2110
|
-
tokenRenewalError
|
|
2111
|
-
);
|
|
2112
|
-
throw tokenRenewalError;
|
|
2113
|
-
})
|
|
2114
|
-
.finally(() => {
|
|
2115
|
-
document.removeEventListener("visibilitychange", () =>
|
|
2116
|
-
this.trackPageVisibility(request.correlationId)
|
|
2117
|
-
);
|
|
2118
|
-
});
|
|
2119
2203
|
}
|
|
2120
2204
|
}
|
|
2121
2205
|
|
|
@@ -2128,7 +2212,6 @@ export class StandardController implements IController {
|
|
|
2128
2212
|
*/
|
|
2129
2213
|
function checkIfRefreshTokenErrorCanBeResolvedSilently(
|
|
2130
2214
|
refreshTokenError: AuthError,
|
|
2131
|
-
silentRequest: CommonSilentFlowRequest,
|
|
2132
2215
|
cacheLookupPolicy: CacheLookupPolicy
|
|
2133
2216
|
): boolean {
|
|
2134
2217
|
const noInteractionRequired = !(
|
|
@@ -106,7 +106,9 @@ export class UnknownOperatingContextController implements IController {
|
|
|
106
106
|
this.config.auth.clientId,
|
|
107
107
|
this.config.cache,
|
|
108
108
|
this.browserCrypto,
|
|
109
|
-
this.logger
|
|
109
|
+
this.logger,
|
|
110
|
+
undefined,
|
|
111
|
+
this.performanceClient
|
|
110
112
|
)
|
|
111
113
|
: DEFAULT_BROWSER_CACHE_MANAGER(
|
|
112
114
|
this.config.auth.clientId,
|
|
@@ -195,6 +195,7 @@ function loadFrameSync(urlNavigate: string): HTMLIFrameElement {
|
|
|
195
195
|
function createHiddenIframe(): HTMLIFrameElement {
|
|
196
196
|
const authFrame = document.createElement("iframe");
|
|
197
197
|
|
|
198
|
+
authFrame.className = "msalSilentIframe";
|
|
198
199
|
authFrame.style.visibility = "hidden";
|
|
199
200
|
authFrame.style.position = "absolute";
|
|
200
201
|
authFrame.style.width = authFrame.style.height = "0";
|