@azure/msal-browser 4.11.1 → 4.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.d.ts +1 -0
- package/dist/app/PublicClientApplication.d.ts.map +1 -1
- package/dist/app/PublicClientApplication.mjs +3 -2
- package/dist/app/PublicClientApplication.mjs.map +1 -1
- package/dist/app/PublicClientNext.mjs +1 -1
- package/dist/broker/nativeBroker/IPlatformAuthHandler.d.ts +12 -0
- package/dist/broker/nativeBroker/IPlatformAuthHandler.d.ts.map +1 -0
- package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
- package/dist/broker/nativeBroker/PlatformAuthDOMHandler.d.ts +30 -0
- package/dist/broker/nativeBroker/PlatformAuthDOMHandler.d.ts.map +1 -0
- package/dist/broker/nativeBroker/PlatformAuthDOMHandler.mjs +143 -0
- package/dist/broker/nativeBroker/PlatformAuthDOMHandler.mjs.map +1 -0
- package/dist/broker/nativeBroker/{NativeMessageHandler.d.ts → PlatformAuthExtensionHandler.d.ts} +16 -16
- package/dist/broker/nativeBroker/PlatformAuthExtensionHandler.d.ts.map +1 -0
- package/dist/broker/nativeBroker/{NativeMessageHandler.mjs → PlatformAuthExtensionHandler.mjs} +66 -58
- package/dist/broker/nativeBroker/PlatformAuthExtensionHandler.mjs.map +1 -0
- package/dist/broker/nativeBroker/PlatformAuthProvider.d.ts +26 -0
- package/dist/broker/nativeBroker/PlatformAuthProvider.d.ts.map +1 -0
- package/dist/broker/nativeBroker/PlatformAuthProvider.mjs +108 -0
- package/dist/broker/nativeBroker/PlatformAuthProvider.mjs.map +1 -0
- package/dist/broker/nativeBroker/{NativeRequest.d.ts → PlatformAuthRequest.d.ts} +34 -3
- package/dist/broker/nativeBroker/PlatformAuthRequest.d.ts.map +1 -0
- package/dist/broker/nativeBroker/{NativeResponse.d.ts → PlatformAuthResponse.d.ts} +24 -2
- package/dist/broker/nativeBroker/PlatformAuthResponse.d.ts.map +1 -0
- package/dist/cache/AccountManager.mjs +1 -1
- package/dist/cache/AsyncMemoryStorage.mjs +1 -1
- package/dist/cache/BrowserCacheManager.d.ts +6 -2
- package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
- package/dist/cache/BrowserCacheManager.mjs +29 -3
- package/dist/cache/BrowserCacheManager.mjs.map +1 -1
- package/dist/cache/CacheHelpers.mjs +1 -1
- package/dist/cache/CookieStorage.mjs +1 -1
- package/dist/cache/DatabaseStorage.mjs +1 -1
- package/dist/cache/LocalStorage.mjs +1 -1
- package/dist/cache/MemoryStorage.mjs +1 -1
- package/dist/cache/SessionStorage.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/IController.d.ts +1 -1
- package/dist/controllers/IController.d.ts.map +1 -1
- package/dist/controllers/NestedAppAuthController.d.ts +1 -1
- package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/dist/controllers/NestedAppAuthController.mjs +4 -2
- package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
- package/dist/controllers/StandardController.d.ts +4 -3
- package/dist/controllers/StandardController.d.ts.map +1 -1
- package/dist/controllers/StandardController.mjs +56 -30
- package/dist/controllers/StandardController.mjs.map +1 -1
- package/dist/controllers/UnknownOperatingContextController.mjs +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.d.ts +10 -1
- package/dist/event/EventMessage.d.ts.map +1 -1
- package/dist/event/EventMessage.mjs +1 -1
- package/dist/event/EventMessage.mjs.map +1 -1
- package/dist/event/EventType.d.ts +1 -0
- package/dist/event/EventType.d.ts.map +1 -1
- package/dist/event/EventType.mjs +2 -1
- package/dist/event/EventType.mjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/interaction_client/BaseInteractionClient.d.ts +3 -3
- package/dist/interaction_client/BaseInteractionClient.d.ts.map +1 -1
- package/dist/interaction_client/BaseInteractionClient.mjs +3 -3
- package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
- package/dist/interaction_client/{NativeInteractionClient.d.ts → PlatformAuthInteractionClient.d.ts} +21 -23
- package/dist/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -0
- package/dist/interaction_client/{NativeInteractionClient.mjs → PlatformAuthInteractionClient.mjs} +80 -111
- package/dist/interaction_client/PlatformAuthInteractionClient.mjs.map +1 -0
- package/dist/interaction_client/PopupClient.d.ts +2 -2
- package/dist/interaction_client/PopupClient.d.ts.map +1 -1
- package/dist/interaction_client/PopupClient.mjs +7 -7
- package/dist/interaction_client/PopupClient.mjs.map +1 -1
- package/dist/interaction_client/RedirectClient.d.ts +2 -2
- package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
- package/dist/interaction_client/RedirectClient.mjs +7 -8
- package/dist/interaction_client/RedirectClient.mjs.map +1 -1
- package/dist/interaction_client/SilentAuthCodeClient.d.ts +2 -2
- package/dist/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
- package/dist/interaction_client/SilentAuthCodeClient.mjs +3 -3
- package/dist/interaction_client/SilentCacheClient.mjs +1 -1
- package/dist/interaction_client/SilentIframeClient.d.ts +2 -2
- package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
- package/dist/interaction_client/SilentIframeClient.mjs +7 -8
- package/dist/interaction_client/SilentIframeClient.mjs.map +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/SilentHandler.mjs +1 -1
- package/dist/naa/BridgeError.mjs +1 -1
- package/dist/naa/BridgeProxy.mjs +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/NestedAppOperatingContext.mjs +1 -1
- package/dist/operatingcontext/StandardOperatingContext.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/protocol/Authorize.d.ts +4 -4
- package/dist/protocol/Authorize.d.ts.map +1 -1
- package/dist/protocol/Authorize.mjs +10 -9
- package/dist/protocol/Authorize.mjs.map +1 -1
- 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.d.ts +8 -1
- package/dist/utils/BrowserConstants.d.ts.map +1 -1
- package/dist/utils/BrowserConstants.mjs +11 -4
- package/dist/utils/BrowserConstants.mjs.map +1 -1
- package/dist/utils/BrowserProtocolUtils.mjs +1 -1
- package/dist/utils/BrowserUtils.mjs +1 -1
- package/dist/utils/MsalFrameStatsUtils.d.ts +3 -0
- package/dist/utils/MsalFrameStatsUtils.d.ts.map +1 -0
- package/dist/utils/MsalFrameStatsUtils.mjs +23 -0
- package/dist/utils/MsalFrameStatsUtils.mjs.map +1 -0
- package/lib/msal-browser.cjs +1600 -1323
- package/lib/msal-browser.cjs.map +1 -1
- package/lib/msal-browser.js +1600 -1323
- package/lib/msal-browser.js.map +1 -1
- package/lib/msal-browser.min.js +66 -66
- package/lib/types/app/PublicClientApplication.d.ts +1 -0
- package/lib/types/app/PublicClientApplication.d.ts.map +1 -1
- package/lib/types/broker/nativeBroker/IPlatformAuthHandler.d.ts +12 -0
- package/lib/types/broker/nativeBroker/IPlatformAuthHandler.d.ts.map +1 -0
- package/lib/types/broker/nativeBroker/PlatformAuthDOMHandler.d.ts +30 -0
- package/lib/types/broker/nativeBroker/PlatformAuthDOMHandler.d.ts.map +1 -0
- package/lib/types/broker/nativeBroker/{NativeMessageHandler.d.ts → PlatformAuthExtensionHandler.d.ts} +16 -16
- package/lib/types/broker/nativeBroker/PlatformAuthExtensionHandler.d.ts.map +1 -0
- package/lib/types/broker/nativeBroker/PlatformAuthProvider.d.ts +26 -0
- package/lib/types/broker/nativeBroker/PlatformAuthProvider.d.ts.map +1 -0
- package/lib/types/broker/nativeBroker/{NativeRequest.d.ts → PlatformAuthRequest.d.ts} +34 -3
- package/lib/types/broker/nativeBroker/PlatformAuthRequest.d.ts.map +1 -0
- package/lib/types/broker/nativeBroker/{NativeResponse.d.ts → PlatformAuthResponse.d.ts} +24 -2
- package/lib/types/broker/nativeBroker/PlatformAuthResponse.d.ts.map +1 -0
- package/lib/types/cache/BrowserCacheManager.d.ts +6 -2
- package/lib/types/cache/BrowserCacheManager.d.ts.map +1 -1
- package/lib/types/controllers/IController.d.ts +1 -1
- package/lib/types/controllers/IController.d.ts.map +1 -1
- package/lib/types/controllers/NestedAppAuthController.d.ts +1 -1
- package/lib/types/controllers/NestedAppAuthController.d.ts.map +1 -1
- package/lib/types/controllers/StandardController.d.ts +4 -3
- package/lib/types/controllers/StandardController.d.ts.map +1 -1
- package/lib/types/event/EventMessage.d.ts +10 -1
- package/lib/types/event/EventMessage.d.ts.map +1 -1
- package/lib/types/event/EventType.d.ts +1 -0
- package/lib/types/event/EventType.d.ts.map +1 -1
- package/lib/types/index.d.ts +2 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/interaction_client/BaseInteractionClient.d.ts +3 -3
- package/lib/types/interaction_client/BaseInteractionClient.d.ts.map +1 -1
- package/lib/types/interaction_client/{NativeInteractionClient.d.ts → PlatformAuthInteractionClient.d.ts} +21 -23
- package/lib/types/interaction_client/PlatformAuthInteractionClient.d.ts.map +1 -0
- package/lib/types/interaction_client/PopupClient.d.ts +2 -2
- package/lib/types/interaction_client/PopupClient.d.ts.map +1 -1
- package/lib/types/interaction_client/RedirectClient.d.ts +2 -2
- package/lib/types/interaction_client/RedirectClient.d.ts.map +1 -1
- package/lib/types/interaction_client/SilentAuthCodeClient.d.ts +2 -2
- package/lib/types/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
- package/lib/types/interaction_client/SilentIframeClient.d.ts +2 -2
- package/lib/types/interaction_client/SilentIframeClient.d.ts.map +1 -1
- package/lib/types/packageMetadata.d.ts +1 -1
- package/lib/types/protocol/Authorize.d.ts +4 -4
- package/lib/types/protocol/Authorize.d.ts.map +1 -1
- package/lib/types/utils/BrowserConstants.d.ts +8 -1
- package/lib/types/utils/BrowserConstants.d.ts.map +1 -1
- package/lib/types/utils/MsalFrameStatsUtils.d.ts +3 -0
- package/lib/types/utils/MsalFrameStatsUtils.d.ts.map +1 -0
- package/package.json +3 -2
- package/src/app/PublicClientApplication.ts +2 -1
- package/src/broker/nativeBroker/IPlatformAuthHandler.ts +17 -0
- package/src/broker/nativeBroker/PlatformAuthDOMHandler.ts +248 -0
- package/src/broker/nativeBroker/{NativeMessageHandler.ts → PlatformAuthExtensionHandler.ts} +90 -79
- package/src/broker/nativeBroker/PlatformAuthProvider.ts +164 -0
- package/src/broker/nativeBroker/{NativeRequest.ts → PlatformAuthRequest.ts} +41 -2
- package/src/broker/nativeBroker/{NativeResponse.ts → PlatformAuthResponse.ts} +25 -1
- package/src/cache/BrowserCacheManager.ts +40 -4
- package/src/controllers/IController.ts +4 -1
- package/src/controllers/NestedAppAuthController.ts +5 -1
- package/src/controllers/StandardController.ts +87 -46
- package/src/event/EventMessage.ts +11 -0
- package/src/event/EventType.ts +1 -0
- package/src/index.ts +3 -0
- package/src/interaction_client/BaseInteractionClient.ts +4 -4
- package/src/interaction_client/{NativeInteractionClient.ts → PlatformAuthInteractionClient.ts} +136 -167
- package/src/interaction_client/PopupClient.ts +8 -7
- package/src/interaction_client/RedirectClient.ts +12 -12
- package/src/interaction_client/SilentAuthCodeClient.ts +3 -3
- package/src/interaction_client/SilentIframeClient.ts +12 -12
- package/src/packageMetadata.ts +1 -1
- package/src/protocol/Authorize.ts +12 -10
- package/src/utils/BrowserConstants.ts +9 -1
- package/src/utils/MsalFrameStatsUtils.ts +32 -0
- package/dist/broker/nativeBroker/NativeMessageHandler.d.ts.map +0 -1
- package/dist/broker/nativeBroker/NativeMessageHandler.mjs.map +0 -1
- package/dist/broker/nativeBroker/NativeRequest.d.ts.map +0 -1
- package/dist/broker/nativeBroker/NativeResponse.d.ts.map +0 -1
- package/dist/interaction_client/NativeInteractionClient.d.ts.map +0 -1
- package/dist/interaction_client/NativeInteractionClient.mjs.map +0 -1
- package/lib/types/broker/nativeBroker/NativeMessageHandler.d.ts.map +0 -1
- package/lib/types/broker/nativeBroker/NativeRequest.d.ts.map +0 -1
- package/lib/types/broker/nativeBroker/NativeResponse.d.ts.map +0 -1
- package/lib/types/interaction_client/NativeInteractionClient.d.ts.map +0 -1
package/lib/msal-browser.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! @azure/msal-browser v4.
|
|
1
|
+
/*! @azure/msal-browser v4.13.0 2025-05-30 */
|
|
2
2
|
'use strict';
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
|
-
/*! @azure/msal-common v15.
|
|
5
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6
6
|
/*
|
|
7
7
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
8
8
|
* Licensed under the MIT License.
|
|
@@ -256,13 +256,6 @@ const Errors = {
|
|
|
256
256
|
INVALID_GRANT_ERROR: "invalid_grant",
|
|
257
257
|
CLIENT_MISMATCH_ERROR: "client_mismatch",
|
|
258
258
|
};
|
|
259
|
-
/**
|
|
260
|
-
* Response codes
|
|
261
|
-
*/
|
|
262
|
-
const ResponseCodes = {
|
|
263
|
-
httpSuccess: 200,
|
|
264
|
-
httpBadRequest: 400,
|
|
265
|
-
};
|
|
266
259
|
/**
|
|
267
260
|
* Region Discovery Sources
|
|
268
261
|
*/
|
|
@@ -305,7 +298,7 @@ const JsonWebTokenTypes = {
|
|
|
305
298
|
// Token renewal offset default in seconds
|
|
306
299
|
const DEFAULT_TOKEN_RENEWAL_OFFSET_SEC = 300;
|
|
307
300
|
|
|
308
|
-
/*! @azure/msal-common v15.
|
|
301
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
309
302
|
/*
|
|
310
303
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
311
304
|
* Licensed under the MIT License.
|
|
@@ -322,7 +315,7 @@ var AuthErrorCodes = /*#__PURE__*/Object.freeze({
|
|
|
322
315
|
unexpectedError: unexpectedError
|
|
323
316
|
});
|
|
324
317
|
|
|
325
|
-
/*! @azure/msal-common v15.
|
|
318
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
326
319
|
|
|
327
320
|
/*
|
|
328
321
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -371,7 +364,7 @@ function createAuthError(code, additionalMessage) {
|
|
|
371
364
|
: AuthErrorMessages[code]);
|
|
372
365
|
}
|
|
373
366
|
|
|
374
|
-
/*! @azure/msal-common v15.
|
|
367
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
375
368
|
/*
|
|
376
369
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
377
370
|
* Licensed under the MIT License.
|
|
@@ -469,7 +462,7 @@ var ClientAuthErrorCodes = /*#__PURE__*/Object.freeze({
|
|
|
469
462
|
userTimeoutReached: userTimeoutReached
|
|
470
463
|
});
|
|
471
464
|
|
|
472
|
-
/*! @azure/msal-common v15.
|
|
465
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
473
466
|
|
|
474
467
|
/*
|
|
475
468
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -721,7 +714,7 @@ function createClientAuthError(errorCode, additionalMessage) {
|
|
|
721
714
|
return new ClientAuthError(errorCode, additionalMessage);
|
|
722
715
|
}
|
|
723
716
|
|
|
724
|
-
/*! @azure/msal-common v15.
|
|
717
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
725
718
|
|
|
726
719
|
/*
|
|
727
720
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -760,7 +753,7 @@ const DEFAULT_CRYPTO_IMPLEMENTATION = {
|
|
|
760
753
|
},
|
|
761
754
|
};
|
|
762
755
|
|
|
763
|
-
/*! @azure/msal-common v15.
|
|
756
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
764
757
|
|
|
765
758
|
/*
|
|
766
759
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -951,12 +944,12 @@ class Logger {
|
|
|
951
944
|
}
|
|
952
945
|
}
|
|
953
946
|
|
|
954
|
-
/*! @azure/msal-common v15.
|
|
947
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
955
948
|
/* eslint-disable header/header */
|
|
956
949
|
const name$1 = "@azure/msal-common";
|
|
957
|
-
const version$1 = "15.
|
|
950
|
+
const version$1 = "15.7.0";
|
|
958
951
|
|
|
959
|
-
/*! @azure/msal-common v15.
|
|
952
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
960
953
|
/*
|
|
961
954
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
962
955
|
* Licensed under the MIT License.
|
|
@@ -976,7 +969,7 @@ const AzureCloudInstance = {
|
|
|
976
969
|
AzureUsGovernment: "https://login.microsoftonline.us",
|
|
977
970
|
};
|
|
978
971
|
|
|
979
|
-
/*! @azure/msal-common v15.
|
|
972
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
980
973
|
|
|
981
974
|
/*
|
|
982
975
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1037,7 +1030,7 @@ function checkMaxAge(authTime, maxAge) {
|
|
|
1037
1030
|
}
|
|
1038
1031
|
}
|
|
1039
1032
|
|
|
1040
|
-
/*! @azure/msal-common v15.
|
|
1033
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1041
1034
|
/*
|
|
1042
1035
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1043
1036
|
* Licensed under the MIT License.
|
|
@@ -1092,7 +1085,7 @@ function wasClockTurnedBack(cachedAt) {
|
|
|
1092
1085
|
return cachedAtSec > nowSeconds();
|
|
1093
1086
|
}
|
|
1094
1087
|
|
|
1095
|
-
/*! @azure/msal-common v15.
|
|
1088
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1096
1089
|
|
|
1097
1090
|
/*
|
|
1098
1091
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1419,7 +1412,7 @@ function isAuthorityMetadataExpired(metadata) {
|
|
|
1419
1412
|
return metadata.expiresAt <= nowSeconds();
|
|
1420
1413
|
}
|
|
1421
1414
|
|
|
1422
|
-
/*! @azure/msal-common v15.
|
|
1415
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1423
1416
|
/*
|
|
1424
1417
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1425
1418
|
* Licensed under the MIT License.
|
|
@@ -1473,7 +1466,7 @@ var ClientConfigurationErrorCodes = /*#__PURE__*/Object.freeze({
|
|
|
1473
1466
|
urlParseError: urlParseError
|
|
1474
1467
|
});
|
|
1475
1468
|
|
|
1476
|
-
/*! @azure/msal-common v15.
|
|
1469
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1477
1470
|
|
|
1478
1471
|
/*
|
|
1479
1472
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1611,7 +1604,7 @@ function createClientConfigurationError(errorCode) {
|
|
|
1611
1604
|
return new ClientConfigurationError(errorCode);
|
|
1612
1605
|
}
|
|
1613
1606
|
|
|
1614
|
-
/*! @azure/msal-common v15.
|
|
1607
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1615
1608
|
/*
|
|
1616
1609
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1617
1610
|
* Licensed under the MIT License.
|
|
@@ -1708,7 +1701,7 @@ class StringUtils {
|
|
|
1708
1701
|
}
|
|
1709
1702
|
}
|
|
1710
1703
|
|
|
1711
|
-
/*! @azure/msal-common v15.
|
|
1704
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1712
1705
|
|
|
1713
1706
|
/*
|
|
1714
1707
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1899,7 +1892,7 @@ class ScopeSet {
|
|
|
1899
1892
|
}
|
|
1900
1893
|
}
|
|
1901
1894
|
|
|
1902
|
-
/*! @azure/msal-common v15.
|
|
1895
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1903
1896
|
|
|
1904
1897
|
/*
|
|
1905
1898
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1939,7 +1932,7 @@ function buildClientInfoFromHomeAccountId(homeAccountId) {
|
|
|
1939
1932
|
};
|
|
1940
1933
|
}
|
|
1941
1934
|
|
|
1942
|
-
/*! @azure/msal-common v15.
|
|
1935
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1943
1936
|
/*
|
|
1944
1937
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1945
1938
|
* Licensed under the MIT License.
|
|
@@ -2018,7 +2011,7 @@ function updateAccountTenantProfileData(baseAccountInfo, tenantProfile, idTokenC
|
|
|
2018
2011
|
return updatedAccountInfo;
|
|
2019
2012
|
}
|
|
2020
2013
|
|
|
2021
|
-
/*! @azure/msal-common v15.
|
|
2014
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2022
2015
|
/*
|
|
2023
2016
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2024
2017
|
* Licensed under the MIT License.
|
|
@@ -2033,7 +2026,7 @@ const AuthorityType = {
|
|
|
2033
2026
|
Ciam: 3,
|
|
2034
2027
|
};
|
|
2035
2028
|
|
|
2036
|
-
/*! @azure/msal-common v15.
|
|
2029
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2037
2030
|
/*
|
|
2038
2031
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2039
2032
|
* Licensed under the MIT License.
|
|
@@ -2055,7 +2048,7 @@ function getTenantIdFromIdTokenClaims(idTokenClaims) {
|
|
|
2055
2048
|
return null;
|
|
2056
2049
|
}
|
|
2057
2050
|
|
|
2058
|
-
/*! @azure/msal-common v15.
|
|
2051
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2059
2052
|
/*
|
|
2060
2053
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2061
2054
|
* Licensed under the MIT License.
|
|
@@ -2079,7 +2072,7 @@ const ProtocolMode = {
|
|
|
2079
2072
|
EAR: "EAR",
|
|
2080
2073
|
};
|
|
2081
2074
|
|
|
2082
|
-
/*! @azure/msal-common v15.
|
|
2075
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2083
2076
|
|
|
2084
2077
|
/*
|
|
2085
2078
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2322,7 +2315,7 @@ class AccountEntity {
|
|
|
2322
2315
|
}
|
|
2323
2316
|
}
|
|
2324
2317
|
|
|
2325
|
-
/*! @azure/msal-common v15.
|
|
2318
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2326
2319
|
|
|
2327
2320
|
/*
|
|
2328
2321
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2387,7 +2380,7 @@ function mapToQueryString(parameters, encodeExtraParams = true, extraQueryParame
|
|
|
2387
2380
|
return queryParameterArray.join("&");
|
|
2388
2381
|
}
|
|
2389
2382
|
|
|
2390
|
-
/*! @azure/msal-common v15.
|
|
2383
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2391
2384
|
|
|
2392
2385
|
/*
|
|
2393
2386
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2551,7 +2544,7 @@ class UrlString {
|
|
|
2551
2544
|
}
|
|
2552
2545
|
}
|
|
2553
2546
|
|
|
2554
|
-
/*! @azure/msal-common v15.
|
|
2547
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2555
2548
|
|
|
2556
2549
|
/*
|
|
2557
2550
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2691,7 +2684,7 @@ function getCloudDiscoveryMetadataFromNetworkResponse(response, authorityHost) {
|
|
|
2691
2684
|
return null;
|
|
2692
2685
|
}
|
|
2693
2686
|
|
|
2694
|
-
/*! @azure/msal-common v15.
|
|
2687
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2695
2688
|
/*
|
|
2696
2689
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2697
2690
|
* Licensed under the MIT License.
|
|
@@ -2699,7 +2692,7 @@ function getCloudDiscoveryMetadataFromNetworkResponse(response, authorityHost) {
|
|
|
2699
2692
|
const cacheQuotaExceededErrorCode = "cache_quota_exceeded";
|
|
2700
2693
|
const cacheUnknownErrorCode = "cache_error_unknown";
|
|
2701
2694
|
|
|
2702
|
-
/*! @azure/msal-common v15.
|
|
2695
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2703
2696
|
|
|
2704
2697
|
/*
|
|
2705
2698
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2726,7 +2719,7 @@ class CacheError extends Error {
|
|
|
2726
2719
|
}
|
|
2727
2720
|
}
|
|
2728
2721
|
|
|
2729
|
-
/*! @azure/msal-common v15.
|
|
2722
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2730
2723
|
|
|
2731
2724
|
/*
|
|
2732
2725
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -3911,7 +3904,7 @@ class DefaultStorageClass extends CacheManager {
|
|
|
3911
3904
|
}
|
|
3912
3905
|
}
|
|
3913
3906
|
|
|
3914
|
-
/*! @azure/msal-common v15.
|
|
3907
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
3915
3908
|
|
|
3916
3909
|
/*
|
|
3917
3910
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -4011,7 +4004,7 @@ function isOidcProtocolMode(config) {
|
|
|
4011
4004
|
return (config.authOptions.authority.options.protocolMode === ProtocolMode.OIDC);
|
|
4012
4005
|
}
|
|
4013
4006
|
|
|
4014
|
-
/*! @azure/msal-common v15.
|
|
4007
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4015
4008
|
/*
|
|
4016
4009
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4017
4010
|
* Licensed under the MIT License.
|
|
@@ -4021,7 +4014,7 @@ const CcsCredentialType = {
|
|
|
4021
4014
|
UPN: "UPN",
|
|
4022
4015
|
};
|
|
4023
4016
|
|
|
4024
|
-
/*! @azure/msal-common v15.
|
|
4017
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4025
4018
|
/*
|
|
4026
4019
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4027
4020
|
* Licensed under the MIT License.
|
|
@@ -4071,7 +4064,7 @@ const INSTANCE_AWARE = "instance_aware";
|
|
|
4071
4064
|
const EAR_JWK = "ear_jwk";
|
|
4072
4065
|
const EAR_JWE_CRYPTO = "ear_jwe_crypto";
|
|
4073
4066
|
|
|
4074
|
-
/*! @azure/msal-common v15.
|
|
4067
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4075
4068
|
|
|
4076
4069
|
/*
|
|
4077
4070
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -4439,7 +4432,7 @@ function addEARParameters(parameters, jwk) {
|
|
|
4439
4432
|
parameters.set(EAR_JWE_CRYPTO, jweCryptoB64Encoded);
|
|
4440
4433
|
}
|
|
4441
4434
|
|
|
4442
|
-
/*! @azure/msal-common v15.
|
|
4435
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4443
4436
|
/*
|
|
4444
4437
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4445
4438
|
* Licensed under the MIT License.
|
|
@@ -4451,7 +4444,7 @@ function isOpenIdConfigResponse(response) {
|
|
|
4451
4444
|
response.hasOwnProperty("jwks_uri"));
|
|
4452
4445
|
}
|
|
4453
4446
|
|
|
4454
|
-
/*! @azure/msal-common v15.
|
|
4447
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4455
4448
|
/*
|
|
4456
4449
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4457
4450
|
* Licensed under the MIT License.
|
|
@@ -4461,7 +4454,7 @@ function isCloudInstanceDiscoveryResponse(response) {
|
|
|
4461
4454
|
response.hasOwnProperty("metadata"));
|
|
4462
4455
|
}
|
|
4463
4456
|
|
|
4464
|
-
/*! @azure/msal-common v15.
|
|
4457
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4465
4458
|
/*
|
|
4466
4459
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4467
4460
|
* Licensed under the MIT License.
|
|
@@ -4471,7 +4464,7 @@ function isCloudInstanceDiscoveryErrorResponse(response) {
|
|
|
4471
4464
|
response.hasOwnProperty("error_description"));
|
|
4472
4465
|
}
|
|
4473
4466
|
|
|
4474
|
-
/*! @azure/msal-common v15.
|
|
4467
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4475
4468
|
/*
|
|
4476
4469
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4477
4470
|
* Licensed under the MIT License.
|
|
@@ -4984,7 +4977,7 @@ const IntFields = new Set([
|
|
|
4984
4977
|
"encryptedCacheExpiredCount",
|
|
4985
4978
|
]);
|
|
4986
4979
|
|
|
4987
|
-
/*! @azure/msal-common v15.
|
|
4980
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4988
4981
|
/*
|
|
4989
4982
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4990
4983
|
* Licensed under the MIT License.
|
|
@@ -5080,7 +5073,7 @@ const invokeAsync = (callback, eventName, logger, telemetryClient, correlationId
|
|
|
5080
5073
|
};
|
|
5081
5074
|
};
|
|
5082
5075
|
|
|
5083
|
-
/*! @azure/msal-common v15.
|
|
5076
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
5084
5077
|
|
|
5085
5078
|
/*
|
|
5086
5079
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5107,15 +5100,13 @@ class RegionDiscovery {
|
|
|
5107
5100
|
const options = RegionDiscovery.IMDS_OPTIONS;
|
|
5108
5101
|
try {
|
|
5109
5102
|
const localIMDSVersionResponse = await invokeAsync(this.getRegionFromIMDS.bind(this), PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.logger, this.performanceClient, this.correlationId)(Constants.IMDS_VERSION, options);
|
|
5110
|
-
if (localIMDSVersionResponse.status ===
|
|
5111
|
-
ResponseCodes.httpSuccess) {
|
|
5103
|
+
if (localIMDSVersionResponse.status === HttpStatus.SUCCESS) {
|
|
5112
5104
|
autodetectedRegionName = localIMDSVersionResponse.body;
|
|
5113
5105
|
regionDiscoveryMetadata.region_source =
|
|
5114
5106
|
RegionDiscoverySources.IMDS;
|
|
5115
5107
|
}
|
|
5116
5108
|
// If the response using the local IMDS version failed, try to fetch the current version of IMDS and retry.
|
|
5117
|
-
if (localIMDSVersionResponse.status ===
|
|
5118
|
-
ResponseCodes.httpBadRequest) {
|
|
5109
|
+
if (localIMDSVersionResponse.status === HttpStatus.BAD_REQUEST) {
|
|
5119
5110
|
const currentIMDSVersion = await invokeAsync(this.getCurrentVersion.bind(this), PerformanceEvents.RegionDiscoveryGetCurrentVersion, this.logger, this.performanceClient, this.correlationId)(options);
|
|
5120
5111
|
if (!currentIMDSVersion) {
|
|
5121
5112
|
regionDiscoveryMetadata.region_source =
|
|
@@ -5123,8 +5114,7 @@ class RegionDiscovery {
|
|
|
5123
5114
|
return null;
|
|
5124
5115
|
}
|
|
5125
5116
|
const currentIMDSVersionResponse = await invokeAsync(this.getRegionFromIMDS.bind(this), PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.logger, this.performanceClient, this.correlationId)(currentIMDSVersion, options);
|
|
5126
|
-
if (currentIMDSVersionResponse.status ===
|
|
5127
|
-
ResponseCodes.httpSuccess) {
|
|
5117
|
+
if (currentIMDSVersionResponse.status === HttpStatus.SUCCESS) {
|
|
5128
5118
|
autodetectedRegionName =
|
|
5129
5119
|
currentIMDSVersionResponse.body;
|
|
5130
5120
|
regionDiscoveryMetadata.region_source =
|
|
@@ -5169,7 +5159,7 @@ class RegionDiscovery {
|
|
|
5169
5159
|
try {
|
|
5170
5160
|
const response = await this.networkInterface.sendGetRequestAsync(`${Constants.IMDS_ENDPOINT}?format=json`, options);
|
|
5171
5161
|
// When IMDS endpoint is called without the api version query param, bad request response comes back with latest version.
|
|
5172
|
-
if (response.status ===
|
|
5162
|
+
if (response.status === HttpStatus.BAD_REQUEST &&
|
|
5173
5163
|
response.body &&
|
|
5174
5164
|
response.body["newest-versions"] &&
|
|
5175
5165
|
response.body["newest-versions"].length > 0) {
|
|
@@ -5189,7 +5179,7 @@ RegionDiscovery.IMDS_OPTIONS = {
|
|
|
5189
5179
|
},
|
|
5190
5180
|
};
|
|
5191
5181
|
|
|
5192
|
-
/*! @azure/msal-common v15.
|
|
5182
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
5193
5183
|
|
|
5194
5184
|
/*
|
|
5195
5185
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6028,7 +6018,7 @@ function buildStaticAuthorityOptions(authOptions) {
|
|
|
6028
6018
|
};
|
|
6029
6019
|
}
|
|
6030
6020
|
|
|
6031
|
-
/*! @azure/msal-common v15.
|
|
6021
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6032
6022
|
|
|
6033
6023
|
/*
|
|
6034
6024
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6059,7 +6049,7 @@ async function createDiscoveredInstance(authorityUri, networkClient, cacheManage
|
|
|
6059
6049
|
}
|
|
6060
6050
|
}
|
|
6061
6051
|
|
|
6062
|
-
/*! @azure/msal-common v15.
|
|
6052
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6063
6053
|
|
|
6064
6054
|
/*
|
|
6065
6055
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6078,7 +6068,7 @@ class ServerError extends AuthError {
|
|
|
6078
6068
|
}
|
|
6079
6069
|
}
|
|
6080
6070
|
|
|
6081
|
-
/*! @azure/msal-common v15.
|
|
6071
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6082
6072
|
/*
|
|
6083
6073
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6084
6074
|
* Licensed under the MIT License.
|
|
@@ -6099,7 +6089,7 @@ function getRequestThumbprint(clientId, request, homeAccountId) {
|
|
|
6099
6089
|
};
|
|
6100
6090
|
}
|
|
6101
6091
|
|
|
6102
|
-
/*! @azure/msal-common v15.
|
|
6092
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6103
6093
|
|
|
6104
6094
|
/*
|
|
6105
6095
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6186,7 +6176,7 @@ class ThrottlingUtils {
|
|
|
6186
6176
|
}
|
|
6187
6177
|
}
|
|
6188
6178
|
|
|
6189
|
-
/*! @azure/msal-common v15.
|
|
6179
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6190
6180
|
|
|
6191
6181
|
/*
|
|
6192
6182
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6217,7 +6207,7 @@ function createNetworkError(error, httpStatus, responseHeaders, additionalError)
|
|
|
6217
6207
|
return new NetworkError(error, httpStatus, responseHeaders);
|
|
6218
6208
|
}
|
|
6219
6209
|
|
|
6220
|
-
/*! @azure/msal-common v15.
|
|
6210
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6221
6211
|
|
|
6222
6212
|
/*
|
|
6223
6213
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6365,7 +6355,7 @@ class BaseClient {
|
|
|
6365
6355
|
}
|
|
6366
6356
|
}
|
|
6367
6357
|
|
|
6368
|
-
/*! @azure/msal-common v15.
|
|
6358
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6369
6359
|
/*
|
|
6370
6360
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6371
6361
|
* Licensed under the MIT License.
|
|
@@ -6391,7 +6381,7 @@ var InteractionRequiredAuthErrorCodes = /*#__PURE__*/Object.freeze({
|
|
|
6391
6381
|
refreshTokenExpired: refreshTokenExpired
|
|
6392
6382
|
});
|
|
6393
6383
|
|
|
6394
|
-
/*! @azure/msal-common v15.
|
|
6384
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6395
6385
|
|
|
6396
6386
|
/*
|
|
6397
6387
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6479,7 +6469,7 @@ function createInteractionRequiredAuthError(errorCode) {
|
|
|
6479
6469
|
return new InteractionRequiredAuthError(errorCode, InteractionRequiredAuthErrorMessages[errorCode]);
|
|
6480
6470
|
}
|
|
6481
6471
|
|
|
6482
|
-
/*! @azure/msal-common v15.
|
|
6472
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6483
6473
|
|
|
6484
6474
|
/*
|
|
6485
6475
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6551,7 +6541,7 @@ class ProtocolUtils {
|
|
|
6551
6541
|
}
|
|
6552
6542
|
}
|
|
6553
6543
|
|
|
6554
|
-
/*! @azure/msal-common v15.
|
|
6544
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6555
6545
|
|
|
6556
6546
|
/*
|
|
6557
6547
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6635,7 +6625,7 @@ class PopTokenGenerator {
|
|
|
6635
6625
|
}
|
|
6636
6626
|
}
|
|
6637
6627
|
|
|
6638
|
-
/*! @azure/msal-common v15.
|
|
6628
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6639
6629
|
/*
|
|
6640
6630
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6641
6631
|
* Licensed under the MIT License.
|
|
@@ -6662,7 +6652,7 @@ class PopTokenGenerator {
|
|
|
6662
6652
|
}
|
|
6663
6653
|
}
|
|
6664
6654
|
|
|
6665
|
-
/*! @azure/msal-common v15.
|
|
6655
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6666
6656
|
|
|
6667
6657
|
/*
|
|
6668
6658
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6993,7 +6983,7 @@ function buildAccountToCache(cacheStorage, authority, homeAccountId, base64Decod
|
|
|
6993
6983
|
return baseAccount;
|
|
6994
6984
|
}
|
|
6995
6985
|
|
|
6996
|
-
/*! @azure/msal-common v15.
|
|
6986
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6997
6987
|
|
|
6998
6988
|
/*
|
|
6999
6989
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7060,7 +7050,7 @@ class RequestValidator {
|
|
|
7060
7050
|
}
|
|
7061
7051
|
}
|
|
7062
7052
|
|
|
7063
|
-
/*! @azure/msal-common v15.
|
|
7053
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7064
7054
|
/*
|
|
7065
7055
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
7066
7056
|
* Licensed under the MIT License.
|
|
@@ -7078,7 +7068,7 @@ async function getClientAssertion(clientAssertion, clientId, tokenEndpoint) {
|
|
|
7078
7068
|
}
|
|
7079
7069
|
}
|
|
7080
7070
|
|
|
7081
|
-
/*! @azure/msal-common v15.
|
|
7071
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7082
7072
|
|
|
7083
7073
|
/*
|
|
7084
7074
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7311,7 +7301,7 @@ class AuthorizationCodeClient extends BaseClient {
|
|
|
7311
7301
|
}
|
|
7312
7302
|
}
|
|
7313
7303
|
|
|
7314
|
-
/*! @azure/msal-common v15.
|
|
7304
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7315
7305
|
|
|
7316
7306
|
/*
|
|
7317
7307
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7520,7 +7510,7 @@ class RefreshTokenClient extends BaseClient {
|
|
|
7520
7510
|
}
|
|
7521
7511
|
}
|
|
7522
7512
|
|
|
7523
|
-
/*! @azure/msal-common v15.
|
|
7513
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7524
7514
|
|
|
7525
7515
|
/*
|
|
7526
7516
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7618,7 +7608,7 @@ class SilentFlowClient extends BaseClient {
|
|
|
7618
7608
|
}
|
|
7619
7609
|
}
|
|
7620
7610
|
|
|
7621
|
-
/*! @azure/msal-common v15.
|
|
7611
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7622
7612
|
|
|
7623
7613
|
/*
|
|
7624
7614
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7633,7 +7623,7 @@ const StubbedNetworkModule = {
|
|
|
7633
7623
|
},
|
|
7634
7624
|
};
|
|
7635
7625
|
|
|
7636
|
-
/*! @azure/msal-common v15.
|
|
7626
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7637
7627
|
|
|
7638
7628
|
/*
|
|
7639
7629
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7857,7 +7847,7 @@ function extractLoginHint(account) {
|
|
|
7857
7847
|
return account.idTokenClaims?.login_hint || null;
|
|
7858
7848
|
}
|
|
7859
7849
|
|
|
7860
|
-
/*! @azure/msal-common v15.
|
|
7850
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7861
7851
|
|
|
7862
7852
|
/*
|
|
7863
7853
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7915,7 +7905,7 @@ class AuthenticationHeaderParser {
|
|
|
7915
7905
|
}
|
|
7916
7906
|
}
|
|
7917
7907
|
|
|
7918
|
-
/*! @azure/msal-common v15.
|
|
7908
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7919
7909
|
|
|
7920
7910
|
/*
|
|
7921
7911
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -8178,7 +8168,7 @@ class ServerTelemetryManager {
|
|
|
8178
8168
|
}
|
|
8179
8169
|
}
|
|
8180
8170
|
|
|
8181
|
-
/*! @azure/msal-common v15.
|
|
8171
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8182
8172
|
/*
|
|
8183
8173
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
8184
8174
|
* Licensed under the MIT License.
|
|
@@ -8186,7 +8176,7 @@ class ServerTelemetryManager {
|
|
|
8186
8176
|
const missingKidError = "missing_kid_error";
|
|
8187
8177
|
const missingAlgError = "missing_alg_error";
|
|
8188
8178
|
|
|
8189
|
-
/*! @azure/msal-common v15.
|
|
8179
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8190
8180
|
|
|
8191
8181
|
/*
|
|
8192
8182
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -8211,7 +8201,7 @@ function createJoseHeaderError(code) {
|
|
|
8211
8201
|
return new JoseHeaderError(code, JoseHeaderErrorMessages[code]);
|
|
8212
8202
|
}
|
|
8213
8203
|
|
|
8214
|
-
/*! @azure/msal-common v15.
|
|
8204
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8215
8205
|
|
|
8216
8206
|
/*
|
|
8217
8207
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -8251,7 +8241,7 @@ class JoseHeader {
|
|
|
8251
8241
|
}
|
|
8252
8242
|
}
|
|
8253
8243
|
|
|
8254
|
-
/*! @azure/msal-common v15.
|
|
8244
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8255
8245
|
|
|
8256
8246
|
/*
|
|
8257
8247
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -8330,7 +8320,7 @@ class StubPerformanceClient {
|
|
|
8330
8320
|
}
|
|
8331
8321
|
}
|
|
8332
8322
|
|
|
8333
|
-
/*! @azure/msal-common v15.
|
|
8323
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8334
8324
|
|
|
8335
8325
|
/*
|
|
8336
8326
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -9349,10 +9339,15 @@ const BrowserConstants = {
|
|
|
9349
9339
|
*/
|
|
9350
9340
|
MSAL_SKU: "msal.js.browser",
|
|
9351
9341
|
};
|
|
9352
|
-
const
|
|
9342
|
+
const PlatformAuthConstants = {
|
|
9353
9343
|
CHANNEL_ID: "53ee284d-920a-4b59-9d30-a60315b26836",
|
|
9354
9344
|
PREFERRED_EXTENSION_ID: "ppnbnpeolgkicgegkbkbjmhlideopiji",
|
|
9355
9345
|
MATS_TELEMETRY: "MATS",
|
|
9346
|
+
MICROSOFT_ENTRA_BROKERID: "MicrosoftEntra",
|
|
9347
|
+
DOM_API_NAME: "DOM API",
|
|
9348
|
+
PLATFORM_DOM_APIS: "get-token-and-sign-out",
|
|
9349
|
+
PLATFORM_DOM_PROVIDER: "PlatformAuthDOMHandler",
|
|
9350
|
+
PLATFORM_EXTENSION_PROVIDER: "PlatformAuthExtensionHandler",
|
|
9356
9351
|
};
|
|
9357
9352
|
const NativeExtensionMethod = {
|
|
9358
9353
|
HandshakeRequest: "Handshake",
|
|
@@ -9390,6 +9385,7 @@ const TemporaryCacheKeys = {
|
|
|
9390
9385
|
const StaticCacheKeys = {
|
|
9391
9386
|
ACCOUNT_KEYS: "msal.account.keys",
|
|
9392
9387
|
TOKEN_KEYS: "msal.token.keys",
|
|
9388
|
+
VERSION: "msal.version",
|
|
9393
9389
|
};
|
|
9394
9390
|
/**
|
|
9395
9391
|
* Cache keys stored in-memory
|
|
@@ -9518,7 +9514,8 @@ const iFrameRenewalPolicies = [
|
|
|
9518
9514
|
];
|
|
9519
9515
|
const LOG_LEVEL_CACHE_KEY = "msal.browser.log.level";
|
|
9520
9516
|
const LOG_PII_CACHE_KEY = "msal.browser.log.pii";
|
|
9521
|
-
const BROWSER_PERF_ENABLED_KEY = "msal.browser.performance.enabled";
|
|
9517
|
+
const BROWSER_PERF_ENABLED_KEY = "msal.browser.performance.enabled";
|
|
9518
|
+
const PLATFORM_AUTH_DOM_SUPPORT = "msal.browser.platform.auth.dom";
|
|
9522
9519
|
|
|
9523
9520
|
/*
|
|
9524
9521
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -10428,7 +10425,7 @@ function buildConfiguration({ auth: userInputAuth, cache: userInputCache, system
|
|
|
10428
10425
|
|
|
10429
10426
|
/* eslint-disable header/header */
|
|
10430
10427
|
const name = "@azure/msal-browser";
|
|
10431
|
-
const version = "4.
|
|
10428
|
+
const version = "4.13.0";
|
|
10432
10429
|
|
|
10433
10430
|
/*
|
|
10434
10431
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -11780,6 +11777,7 @@ const EventType = {
|
|
|
11780
11777
|
LOGOUT_FAILURE: "msal:logoutFailure",
|
|
11781
11778
|
LOGOUT_END: "msal:logoutEnd",
|
|
11782
11779
|
RESTORE_FROM_BFCACHE: "msal:restoreFromBFCache",
|
|
11780
|
+
BROKER_CONNECTION_ESTABLISHED: "msal:brokerConnectionEstablished",
|
|
11783
11781
|
};
|
|
11784
11782
|
|
|
11785
11783
|
/*
|
|
@@ -11805,6 +11803,20 @@ class BrowserCacheManager extends CacheManager {
|
|
|
11805
11803
|
}
|
|
11806
11804
|
async initialize(correlationId) {
|
|
11807
11805
|
await this.browserStorage.initialize(correlationId);
|
|
11806
|
+
this.trackVersionChanges(correlationId);
|
|
11807
|
+
}
|
|
11808
|
+
/**
|
|
11809
|
+
* Tracks upgrades and downgrades for telemetry and debugging purposes
|
|
11810
|
+
*/
|
|
11811
|
+
trackVersionChanges(correlationId) {
|
|
11812
|
+
const previousVersion = this.browserStorage.getItem(StaticCacheKeys.VERSION);
|
|
11813
|
+
if (previousVersion) {
|
|
11814
|
+
this.logger.info(`MSAL.js was last initialized by version: ${previousVersion}`);
|
|
11815
|
+
this.performanceClient.addFields({ previousLibraryVersion: previousVersion }, correlationId);
|
|
11816
|
+
}
|
|
11817
|
+
if (previousVersion !== version) {
|
|
11818
|
+
this.browserStorage.setItem(StaticCacheKeys.VERSION, version);
|
|
11819
|
+
}
|
|
11808
11820
|
}
|
|
11809
11821
|
/**
|
|
11810
11822
|
* Parses passed value as JSON object, JSON.parse() will throw an error.
|
|
@@ -12525,7 +12537,17 @@ class BrowserCacheManager extends CacheManager {
|
|
|
12525
12537
|
getInteractionInProgress() {
|
|
12526
12538
|
const key = `${Constants.CACHE_PREFIX}.${TemporaryCacheKeys.INTERACTION_STATUS_KEY}`;
|
|
12527
12539
|
const value = this.getTemporaryCache(key, false);
|
|
12528
|
-
|
|
12540
|
+
try {
|
|
12541
|
+
return value ? JSON.parse(value) : null;
|
|
12542
|
+
}
|
|
12543
|
+
catch (e) {
|
|
12544
|
+
// Remove interaction and other temp keys if interaction status can't be parsed
|
|
12545
|
+
this.logger.error(`Cannot parse interaction status. Removing temporary cache items and clearing url hash. Retrying interaction should fix the error`);
|
|
12546
|
+
this.removeTemporaryItem(key);
|
|
12547
|
+
this.resetRequestCache();
|
|
12548
|
+
clearHash(window);
|
|
12549
|
+
return null;
|
|
12550
|
+
}
|
|
12529
12551
|
}
|
|
12530
12552
|
setInteractionInProgress(inProgress, type = INTERACTION_TYPE.SIGNIN) {
|
|
12531
12553
|
// Ensure we don't overwrite interaction in progress for a different clientId
|
|
@@ -12874,14 +12896,14 @@ class EventHandler {
|
|
|
12874
12896
|
* Licensed under the MIT License.
|
|
12875
12897
|
*/
|
|
12876
12898
|
class BaseInteractionClient {
|
|
12877
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
12899
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthProvider, correlationId) {
|
|
12878
12900
|
this.config = config;
|
|
12879
12901
|
this.browserStorage = storageImpl;
|
|
12880
12902
|
this.browserCrypto = browserCrypto;
|
|
12881
12903
|
this.networkClient = this.config.system.networkClient;
|
|
12882
12904
|
this.eventHandler = eventHandler;
|
|
12883
12905
|
this.navigationClient = navigationClient;
|
|
12884
|
-
this.
|
|
12906
|
+
this.platformAuthProvider = platformAuthProvider;
|
|
12885
12907
|
this.correlationId = correlationId || createNewGuid();
|
|
12886
12908
|
this.logger = logger.clone(BrowserConstants.MSAL_SKU, version, this.correlationId);
|
|
12887
12909
|
this.performanceClient = performanceClient;
|
|
@@ -13237,6 +13259,159 @@ class StandardInteractionClient extends BaseInteractionClient {
|
|
|
13237
13259
|
}
|
|
13238
13260
|
}
|
|
13239
13261
|
|
|
13262
|
+
/*
|
|
13263
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13264
|
+
* Licensed under the MIT License.
|
|
13265
|
+
*/
|
|
13266
|
+
/**
|
|
13267
|
+
* Extracts the BrowserStateObject from the state string.
|
|
13268
|
+
* @param browserCrypto
|
|
13269
|
+
* @param state
|
|
13270
|
+
*/
|
|
13271
|
+
function extractBrowserRequestState(browserCrypto, state) {
|
|
13272
|
+
if (!state) {
|
|
13273
|
+
return null;
|
|
13274
|
+
}
|
|
13275
|
+
try {
|
|
13276
|
+
const requestStateObj = ProtocolUtils.parseRequestState(browserCrypto, state);
|
|
13277
|
+
return requestStateObj.libraryState.meta;
|
|
13278
|
+
}
|
|
13279
|
+
catch (e) {
|
|
13280
|
+
throw createClientAuthError(invalidState);
|
|
13281
|
+
}
|
|
13282
|
+
}
|
|
13283
|
+
|
|
13284
|
+
/*
|
|
13285
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13286
|
+
* Licensed under the MIT License.
|
|
13287
|
+
*/
|
|
13288
|
+
function deserializeResponse(responseString, responseLocation, logger) {
|
|
13289
|
+
// Deserialize hash fragment response parameters.
|
|
13290
|
+
const serverParams = getDeserializedResponse(responseString);
|
|
13291
|
+
if (!serverParams) {
|
|
13292
|
+
if (!stripLeadingHashOrQuery(responseString)) {
|
|
13293
|
+
// Hash or Query string is empty
|
|
13294
|
+
logger.error(`The request has returned to the redirectUri but a ${responseLocation} is not present. It's likely that the ${responseLocation} has been removed or the page has been redirected by code running on the redirectUri page.`);
|
|
13295
|
+
throw createBrowserAuthError(hashEmptyError);
|
|
13296
|
+
}
|
|
13297
|
+
else {
|
|
13298
|
+
logger.error(`A ${responseLocation} is present in the iframe but it does not contain known properties. It's likely that the ${responseLocation} has been replaced by code running on the redirectUri page.`);
|
|
13299
|
+
logger.errorPii(`The ${responseLocation} detected is: ${responseString}`);
|
|
13300
|
+
throw createBrowserAuthError(hashDoesNotContainKnownProperties);
|
|
13301
|
+
}
|
|
13302
|
+
}
|
|
13303
|
+
return serverParams;
|
|
13304
|
+
}
|
|
13305
|
+
/**
|
|
13306
|
+
* Returns the interaction type that the response object belongs to
|
|
13307
|
+
*/
|
|
13308
|
+
function validateInteractionType(response, browserCrypto, interactionType) {
|
|
13309
|
+
if (!response.state) {
|
|
13310
|
+
throw createBrowserAuthError(noStateInHash);
|
|
13311
|
+
}
|
|
13312
|
+
const platformStateObj = extractBrowserRequestState(browserCrypto, response.state);
|
|
13313
|
+
if (!platformStateObj) {
|
|
13314
|
+
throw createBrowserAuthError(unableToParseState);
|
|
13315
|
+
}
|
|
13316
|
+
if (platformStateObj.interactionType !== interactionType) {
|
|
13317
|
+
throw createBrowserAuthError(stateInteractionTypeMismatch);
|
|
13318
|
+
}
|
|
13319
|
+
}
|
|
13320
|
+
|
|
13321
|
+
/*
|
|
13322
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13323
|
+
* Licensed under the MIT License.
|
|
13324
|
+
*/
|
|
13325
|
+
/**
|
|
13326
|
+
* Abstract class which defines operations for a browser interaction handling class.
|
|
13327
|
+
*/
|
|
13328
|
+
class InteractionHandler {
|
|
13329
|
+
constructor(authCodeModule, storageImpl, authCodeRequest, logger, performanceClient) {
|
|
13330
|
+
this.authModule = authCodeModule;
|
|
13331
|
+
this.browserStorage = storageImpl;
|
|
13332
|
+
this.authCodeRequest = authCodeRequest;
|
|
13333
|
+
this.logger = logger;
|
|
13334
|
+
this.performanceClient = performanceClient;
|
|
13335
|
+
}
|
|
13336
|
+
/**
|
|
13337
|
+
* Function to handle response parameters from hash.
|
|
13338
|
+
* @param locationHash
|
|
13339
|
+
*/
|
|
13340
|
+
async handleCodeResponse(response, request) {
|
|
13341
|
+
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponse, request.correlationId);
|
|
13342
|
+
let authCodeResponse;
|
|
13343
|
+
try {
|
|
13344
|
+
authCodeResponse = getAuthorizationCodePayload(response, request.state);
|
|
13345
|
+
}
|
|
13346
|
+
catch (e) {
|
|
13347
|
+
if (e instanceof ServerError &&
|
|
13348
|
+
e.subError === userCancelled) {
|
|
13349
|
+
// Translate server error caused by user closing native prompt to corresponding first class MSAL error
|
|
13350
|
+
throw createBrowserAuthError(userCancelled);
|
|
13351
|
+
}
|
|
13352
|
+
else {
|
|
13353
|
+
throw e;
|
|
13354
|
+
}
|
|
13355
|
+
}
|
|
13356
|
+
return invokeAsync(this.handleCodeResponseFromServer.bind(this), PerformanceEvents.HandleCodeResponseFromServer, this.logger, this.performanceClient, request.correlationId)(authCodeResponse, request);
|
|
13357
|
+
}
|
|
13358
|
+
/**
|
|
13359
|
+
* Process auth code response from AAD
|
|
13360
|
+
* @param authCodeResponse
|
|
13361
|
+
* @param state
|
|
13362
|
+
* @param authority
|
|
13363
|
+
* @param networkModule
|
|
13364
|
+
* @returns
|
|
13365
|
+
*/
|
|
13366
|
+
async handleCodeResponseFromServer(authCodeResponse, request, validateNonce = true) {
|
|
13367
|
+
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponseFromServer, request.correlationId);
|
|
13368
|
+
this.logger.trace("InteractionHandler.handleCodeResponseFromServer called");
|
|
13369
|
+
// Assign code to request
|
|
13370
|
+
this.authCodeRequest.code = authCodeResponse.code;
|
|
13371
|
+
// Check for new cloud instance
|
|
13372
|
+
if (authCodeResponse.cloud_instance_host_name) {
|
|
13373
|
+
await invokeAsync(this.authModule.updateAuthority.bind(this.authModule), PerformanceEvents.UpdateTokenEndpointAuthority, this.logger, this.performanceClient, request.correlationId)(authCodeResponse.cloud_instance_host_name, request.correlationId);
|
|
13374
|
+
}
|
|
13375
|
+
// Nonce validation not needed when redirect not involved (e.g. hybrid spa, renewing token via rt)
|
|
13376
|
+
if (validateNonce) {
|
|
13377
|
+
// TODO: Assigning "response nonce" to "request nonce" is confusing. Refactor the function doing validation to accept request nonce directly
|
|
13378
|
+
authCodeResponse.nonce = request.nonce || undefined;
|
|
13379
|
+
}
|
|
13380
|
+
authCodeResponse.state = request.state;
|
|
13381
|
+
// Add CCS parameters if available
|
|
13382
|
+
if (authCodeResponse.client_info) {
|
|
13383
|
+
this.authCodeRequest.clientInfo = authCodeResponse.client_info;
|
|
13384
|
+
}
|
|
13385
|
+
else {
|
|
13386
|
+
const ccsCred = this.createCcsCredentials(request);
|
|
13387
|
+
if (ccsCred) {
|
|
13388
|
+
this.authCodeRequest.ccsCredential = ccsCred;
|
|
13389
|
+
}
|
|
13390
|
+
}
|
|
13391
|
+
// Acquire token with retrieved code.
|
|
13392
|
+
const tokenResponse = (await invokeAsync(this.authModule.acquireToken.bind(this.authModule), PerformanceEvents.AuthClientAcquireToken, this.logger, this.performanceClient, request.correlationId)(this.authCodeRequest, authCodeResponse));
|
|
13393
|
+
return tokenResponse;
|
|
13394
|
+
}
|
|
13395
|
+
/**
|
|
13396
|
+
* Build ccs creds if available
|
|
13397
|
+
*/
|
|
13398
|
+
createCcsCredentials(request) {
|
|
13399
|
+
if (request.account) {
|
|
13400
|
+
return {
|
|
13401
|
+
credential: request.account.homeAccountId,
|
|
13402
|
+
type: CcsCredentialType.HOME_ACCOUNT_ID,
|
|
13403
|
+
};
|
|
13404
|
+
}
|
|
13405
|
+
else if (request.loginHint) {
|
|
13406
|
+
return {
|
|
13407
|
+
credential: request.loginHint,
|
|
13408
|
+
type: CcsCredentialType.UPN,
|
|
13409
|
+
};
|
|
13410
|
+
}
|
|
13411
|
+
return null;
|
|
13412
|
+
}
|
|
13413
|
+
}
|
|
13414
|
+
|
|
13240
13415
|
/*
|
|
13241
13416
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13242
13417
|
* Licensed under the MIT License.
|
|
@@ -13321,930 +13496,1153 @@ function createNativeAuthError(code, description, ext) {
|
|
|
13321
13496
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13322
13497
|
* Licensed under the MIT License.
|
|
13323
13498
|
*/
|
|
13324
|
-
class
|
|
13325
|
-
constructor(logger, handshakeTimeoutMs, performanceClient, extensionId) {
|
|
13326
|
-
this.logger = logger;
|
|
13327
|
-
this.handshakeTimeoutMs = handshakeTimeoutMs;
|
|
13328
|
-
this.extensionId = extensionId;
|
|
13329
|
-
this.resolvers = new Map(); // Used for non-handshake messages
|
|
13330
|
-
this.handshakeResolvers = new Map(); // Used for handshake messages
|
|
13331
|
-
this.messageChannel = new MessageChannel();
|
|
13332
|
-
this.windowListener = this.onWindowMessage.bind(this); // Window event callback doesn't have access to 'this' unless it's bound
|
|
13333
|
-
this.performanceClient = performanceClient;
|
|
13334
|
-
this.handshakeEvent = performanceClient.startMeasurement(PerformanceEvents.NativeMessageHandlerHandshake);
|
|
13335
|
-
}
|
|
13499
|
+
class SilentCacheClient extends StandardInteractionClient {
|
|
13336
13500
|
/**
|
|
13337
|
-
*
|
|
13338
|
-
* @param
|
|
13501
|
+
* Returns unexpired tokens from the cache, if available
|
|
13502
|
+
* @param silentRequest
|
|
13339
13503
|
*/
|
|
13340
|
-
async
|
|
13341
|
-
this.
|
|
13342
|
-
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13346
|
-
|
|
13347
|
-
|
|
13348
|
-
|
|
13349
|
-
this.logger.tracePii(`NativeMessageHandler - Sending request to browser extension: ${JSON.stringify(req)}`);
|
|
13350
|
-
this.messageChannel.port1.postMessage(req);
|
|
13351
|
-
return new Promise((resolve, reject) => {
|
|
13352
|
-
this.resolvers.set(req.responseId, { resolve, reject });
|
|
13504
|
+
async acquireToken(silentRequest) {
|
|
13505
|
+
this.performanceClient.addQueueMeasurement(PerformanceEvents.SilentCacheClientAcquireToken, silentRequest.correlationId);
|
|
13506
|
+
// Telemetry manager only used to increment cacheHits here
|
|
13507
|
+
const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenSilent_silentFlow);
|
|
13508
|
+
const clientConfig = await invokeAsync(this.getClientConfiguration.bind(this), PerformanceEvents.StandardInteractionClientGetClientConfiguration, this.logger, this.performanceClient, this.correlationId)({
|
|
13509
|
+
serverTelemetryManager,
|
|
13510
|
+
requestAuthority: silentRequest.authority,
|
|
13511
|
+
requestAzureCloudOptions: silentRequest.azureCloudOptions,
|
|
13512
|
+
account: silentRequest.account,
|
|
13353
13513
|
});
|
|
13354
|
-
|
|
13355
|
-
|
|
13356
|
-
* Returns an instance of the MessageHandler that has successfully established a connection with an extension
|
|
13357
|
-
* @param {Logger} logger
|
|
13358
|
-
* @param {number} handshakeTimeoutMs
|
|
13359
|
-
* @param {IPerformanceClient} performanceClient
|
|
13360
|
-
* @param {ICrypto} crypto
|
|
13361
|
-
*/
|
|
13362
|
-
static async createProvider(logger, handshakeTimeoutMs, performanceClient) {
|
|
13363
|
-
logger.trace("NativeMessageHandler - createProvider called.");
|
|
13514
|
+
const silentAuthClient = new SilentFlowClient(clientConfig, this.performanceClient);
|
|
13515
|
+
this.logger.verbose("Silent auth client created");
|
|
13364
13516
|
try {
|
|
13365
|
-
const
|
|
13366
|
-
|
|
13367
|
-
|
|
13517
|
+
const response = await invokeAsync(silentAuthClient.acquireCachedToken.bind(silentAuthClient), PerformanceEvents.SilentFlowClientAcquireCachedToken, this.logger, this.performanceClient, silentRequest.correlationId)(silentRequest);
|
|
13518
|
+
const authResponse = response[0];
|
|
13519
|
+
this.performanceClient.addFields({
|
|
13520
|
+
fromCache: true,
|
|
13521
|
+
}, silentRequest.correlationId);
|
|
13522
|
+
return authResponse;
|
|
13368
13523
|
}
|
|
13369
|
-
catch (
|
|
13370
|
-
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
|
|
13524
|
+
catch (error) {
|
|
13525
|
+
if (error instanceof BrowserAuthError &&
|
|
13526
|
+
error.errorCode === cryptoKeyNotFound) {
|
|
13527
|
+
this.logger.verbose("Signing keypair for bound access token not found. Refreshing bound access token and generating a new crypto keypair.");
|
|
13528
|
+
}
|
|
13529
|
+
throw error;
|
|
13374
13530
|
}
|
|
13375
13531
|
}
|
|
13376
13532
|
/**
|
|
13377
|
-
*
|
|
13533
|
+
* API to silenty clear the browser cache.
|
|
13534
|
+
* @param logoutRequest
|
|
13378
13535
|
*/
|
|
13379
|
-
|
|
13380
|
-
this.logger.
|
|
13381
|
-
|
|
13382
|
-
|
|
13383
|
-
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
this.
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
* This typically suggests an event handler stopped propagation of the Handshake request but did not respond to it on the MessageChannel port
|
|
13405
|
-
*/
|
|
13406
|
-
window.removeEventListener("message", this.windowListener, false);
|
|
13407
|
-
this.messageChannel.port1.close();
|
|
13408
|
-
this.messageChannel.port2.close();
|
|
13409
|
-
this.handshakeEvent.end({
|
|
13410
|
-
extensionHandshakeTimedOut: true,
|
|
13411
|
-
success: false,
|
|
13412
|
-
});
|
|
13413
|
-
reject(createBrowserAuthError(nativeHandshakeTimeout));
|
|
13414
|
-
this.handshakeResolvers.delete(req.responseId);
|
|
13415
|
-
}, this.handshakeTimeoutMs); // Use a reasonable timeout in milliseconds here
|
|
13536
|
+
logout(logoutRequest) {
|
|
13537
|
+
this.logger.verbose("logoutRedirect called");
|
|
13538
|
+
const validLogoutRequest = this.initializeLogoutRequest(logoutRequest);
|
|
13539
|
+
return this.clearCacheOnLogout(validLogoutRequest?.account);
|
|
13540
|
+
}
|
|
13541
|
+
}
|
|
13542
|
+
|
|
13543
|
+
/*
|
|
13544
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13545
|
+
* Licensed under the MIT License.
|
|
13546
|
+
*/
|
|
13547
|
+
class PlatformAuthInteractionClient extends BaseInteractionClient {
|
|
13548
|
+
constructor(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, provider, accountId, nativeStorageImpl, correlationId) {
|
|
13549
|
+
super(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13550
|
+
this.apiId = apiId;
|
|
13551
|
+
this.accountId = accountId;
|
|
13552
|
+
this.platformAuthProvider = provider;
|
|
13553
|
+
this.nativeStorageManager = nativeStorageImpl;
|
|
13554
|
+
this.silentCacheClient = new SilentCacheClient(config, this.nativeStorageManager, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13555
|
+
const extensionName = this.platformAuthProvider.getExtensionName();
|
|
13556
|
+
this.skus = ServerTelemetryManager.makeExtraSkuString({
|
|
13557
|
+
libraryName: BrowserConstants.MSAL_SKU,
|
|
13558
|
+
libraryVersion: version,
|
|
13559
|
+
extensionName: extensionName,
|
|
13560
|
+
extensionVersion: this.platformAuthProvider.getExtensionVersion(),
|
|
13416
13561
|
});
|
|
13417
13562
|
}
|
|
13418
13563
|
/**
|
|
13419
|
-
*
|
|
13420
|
-
* @param
|
|
13564
|
+
* Adds SKUs to request extra query parameters
|
|
13565
|
+
* @param request {PlatformAuthRequest}
|
|
13566
|
+
* @private
|
|
13421
13567
|
*/
|
|
13422
|
-
|
|
13423
|
-
|
|
13424
|
-
|
|
13425
|
-
|
|
13426
|
-
|
|
13427
|
-
}
|
|
13428
|
-
const request = event.data;
|
|
13429
|
-
if (!request.channel ||
|
|
13430
|
-
request.channel !== NativeConstants.CHANNEL_ID) {
|
|
13431
|
-
return;
|
|
13432
|
-
}
|
|
13433
|
-
if (request.extensionId && request.extensionId !== this.extensionId) {
|
|
13434
|
-
return;
|
|
13435
|
-
}
|
|
13436
|
-
if (request.body.method === NativeExtensionMethod.HandshakeRequest) {
|
|
13437
|
-
const handshakeResolver = this.handshakeResolvers.get(request.responseId);
|
|
13438
|
-
/*
|
|
13439
|
-
* Filter out responses with no matched resolvers sooner to keep channel ports open while waiting for
|
|
13440
|
-
* the proper response.
|
|
13441
|
-
*/
|
|
13442
|
-
if (!handshakeResolver) {
|
|
13443
|
-
this.logger.trace(`NativeMessageHandler.onWindowMessage - resolver can't be found for request ${request.responseId}`);
|
|
13444
|
-
return;
|
|
13445
|
-
}
|
|
13446
|
-
// If we receive this message back it means no extension intercepted the request, meaning no extension supporting handshake protocol is installed
|
|
13447
|
-
this.logger.verbose(request.extensionId
|
|
13448
|
-
? `Extension with id: ${request.extensionId} not installed`
|
|
13449
|
-
: "No extension installed");
|
|
13450
|
-
clearTimeout(this.timeoutId);
|
|
13451
|
-
this.messageChannel.port1.close();
|
|
13452
|
-
this.messageChannel.port2.close();
|
|
13453
|
-
window.removeEventListener("message", this.windowListener, false);
|
|
13454
|
-
this.handshakeEvent.end({
|
|
13455
|
-
success: false,
|
|
13456
|
-
extensionInstalled: false,
|
|
13457
|
-
});
|
|
13458
|
-
handshakeResolver.reject(createBrowserAuthError(nativeExtensionNotInstalled));
|
|
13459
|
-
}
|
|
13568
|
+
addRequestSKUs(request) {
|
|
13569
|
+
request.extraParameters = {
|
|
13570
|
+
...request.extraParameters,
|
|
13571
|
+
[X_CLIENT_EXTRA_SKU]: this.skus,
|
|
13572
|
+
};
|
|
13460
13573
|
}
|
|
13461
13574
|
/**
|
|
13462
|
-
*
|
|
13463
|
-
* @param
|
|
13575
|
+
* Acquire token from native platform via browser extension
|
|
13576
|
+
* @param request
|
|
13464
13577
|
*/
|
|
13465
|
-
|
|
13466
|
-
this.
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
const
|
|
13578
|
+
async acquireToken(request, cacheLookupPolicy) {
|
|
13579
|
+
this.performanceClient.addQueueMeasurement(PerformanceEvents.NativeInteractionClientAcquireToken, request.correlationId);
|
|
13580
|
+
this.logger.trace("NativeInteractionClient - acquireToken called.");
|
|
13581
|
+
// start the perf measurement
|
|
13582
|
+
const nativeATMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.NativeInteractionClientAcquireToken, request.correlationId);
|
|
13583
|
+
const reqTimestamp = nowSeconds();
|
|
13584
|
+
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
13470
13585
|
try {
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
else if (response.result) {
|
|
13483
|
-
if (response.result["code"] &&
|
|
13484
|
-
response.result["description"]) {
|
|
13485
|
-
resolver.reject(createNativeAuthError(response.result["code"], response.result["description"], response.result["ext"]));
|
|
13486
|
-
}
|
|
13487
|
-
else {
|
|
13488
|
-
resolver.resolve(response.result);
|
|
13489
|
-
}
|
|
13490
|
-
}
|
|
13491
|
-
else {
|
|
13492
|
-
throw createAuthError(unexpectedError, "Event does not contain result.");
|
|
13493
|
-
}
|
|
13494
|
-
this.resolvers.delete(request.responseId);
|
|
13586
|
+
// initialize native request
|
|
13587
|
+
const nativeRequest = await this.initializeNativeRequest(request);
|
|
13588
|
+
// check if the tokens can be retrieved from internal cache
|
|
13589
|
+
try {
|
|
13590
|
+
const result = await this.acquireTokensFromCache(this.accountId, nativeRequest);
|
|
13591
|
+
nativeATMeasurement.end({
|
|
13592
|
+
success: true,
|
|
13593
|
+
isNativeBroker: false,
|
|
13594
|
+
fromCache: true,
|
|
13595
|
+
});
|
|
13596
|
+
return result;
|
|
13495
13597
|
}
|
|
13496
|
-
|
|
13497
|
-
if (
|
|
13498
|
-
this.logger.
|
|
13499
|
-
|
|
13598
|
+
catch (e) {
|
|
13599
|
+
if (cacheLookupPolicy === CacheLookupPolicy.AccessToken) {
|
|
13600
|
+
this.logger.info("MSAL internal Cache does not contain tokens, return error as per cache policy");
|
|
13601
|
+
throw e;
|
|
13500
13602
|
}
|
|
13501
|
-
|
|
13502
|
-
|
|
13503
|
-
|
|
13504
|
-
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13603
|
+
// continue with a native call for any and all errors
|
|
13604
|
+
this.logger.info("MSAL internal Cache does not contain tokens, proceed to make a native call");
|
|
13605
|
+
}
|
|
13606
|
+
const validatedResponse = await this.platformAuthProvider.sendMessage(nativeRequest);
|
|
13607
|
+
return await this.handleNativeResponse(validatedResponse, nativeRequest, reqTimestamp)
|
|
13608
|
+
.then((result) => {
|
|
13609
|
+
nativeATMeasurement.end({
|
|
13508
13610
|
success: true,
|
|
13611
|
+
isNativeBroker: true,
|
|
13612
|
+
requestId: result.requestId,
|
|
13509
13613
|
});
|
|
13510
|
-
|
|
13511
|
-
|
|
13512
|
-
}
|
|
13513
|
-
|
|
13614
|
+
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
13615
|
+
return result;
|
|
13616
|
+
})
|
|
13617
|
+
.catch((error) => {
|
|
13618
|
+
nativeATMeasurement.end({
|
|
13619
|
+
success: false,
|
|
13620
|
+
errorCode: error.errorCode,
|
|
13621
|
+
subErrorCode: error.subError,
|
|
13622
|
+
isNativeBroker: true,
|
|
13623
|
+
});
|
|
13624
|
+
throw error;
|
|
13625
|
+
});
|
|
13514
13626
|
}
|
|
13515
|
-
catch (
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
this.logger.errorPii(`Unable to parse ${event}`);
|
|
13519
|
-
if (resolver) {
|
|
13520
|
-
resolver.reject(err);
|
|
13521
|
-
}
|
|
13522
|
-
else if (handshakeResolver) {
|
|
13523
|
-
handshakeResolver.reject(err);
|
|
13627
|
+
catch (e) {
|
|
13628
|
+
if (e instanceof NativeAuthError) {
|
|
13629
|
+
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
|
|
13524
13630
|
}
|
|
13631
|
+
throw e;
|
|
13525
13632
|
}
|
|
13526
13633
|
}
|
|
13527
13634
|
/**
|
|
13528
|
-
*
|
|
13529
|
-
* @
|
|
13635
|
+
* Creates silent flow request
|
|
13636
|
+
* @param request
|
|
13637
|
+
* @param cachedAccount
|
|
13638
|
+
* @returns CommonSilentFlowRequest
|
|
13530
13639
|
*/
|
|
13531
|
-
|
|
13532
|
-
return
|
|
13640
|
+
createSilentCacheRequest(request, cachedAccount) {
|
|
13641
|
+
return {
|
|
13642
|
+
authority: request.authority,
|
|
13643
|
+
correlationId: this.correlationId,
|
|
13644
|
+
scopes: ScopeSet.fromString(request.scope).asArray(),
|
|
13645
|
+
account: cachedAccount,
|
|
13646
|
+
forceRefresh: false,
|
|
13647
|
+
};
|
|
13533
13648
|
}
|
|
13534
13649
|
/**
|
|
13535
|
-
*
|
|
13536
|
-
* @
|
|
13650
|
+
* Fetches the tokens from the cache if un-expired
|
|
13651
|
+
* @param nativeAccountId
|
|
13652
|
+
* @param request
|
|
13653
|
+
* @returns authenticationResult
|
|
13537
13654
|
*/
|
|
13538
|
-
|
|
13539
|
-
|
|
13655
|
+
async acquireTokensFromCache(nativeAccountId, request) {
|
|
13656
|
+
if (!nativeAccountId) {
|
|
13657
|
+
this.logger.warning("NativeInteractionClient:acquireTokensFromCache - No nativeAccountId provided");
|
|
13658
|
+
throw createClientAuthError(noAccountFound);
|
|
13659
|
+
}
|
|
13660
|
+
// fetch the account from browser cache
|
|
13661
|
+
const account = this.browserStorage.getBaseAccountInfo({
|
|
13662
|
+
nativeAccountId,
|
|
13663
|
+
});
|
|
13664
|
+
if (!account) {
|
|
13665
|
+
throw createClientAuthError(noAccountFound);
|
|
13666
|
+
}
|
|
13667
|
+
// leverage silent flow for cached tokens retrieval
|
|
13668
|
+
try {
|
|
13669
|
+
const silentRequest = this.createSilentCacheRequest(request, account);
|
|
13670
|
+
const result = await this.silentCacheClient.acquireToken(silentRequest);
|
|
13671
|
+
const fullAccount = {
|
|
13672
|
+
...account,
|
|
13673
|
+
idTokenClaims: result?.idTokenClaims,
|
|
13674
|
+
idToken: result?.idToken,
|
|
13675
|
+
};
|
|
13676
|
+
return {
|
|
13677
|
+
...result,
|
|
13678
|
+
account: fullAccount,
|
|
13679
|
+
};
|
|
13680
|
+
}
|
|
13681
|
+
catch (e) {
|
|
13682
|
+
throw e;
|
|
13683
|
+
}
|
|
13540
13684
|
}
|
|
13541
13685
|
/**
|
|
13542
|
-
*
|
|
13543
|
-
* @param
|
|
13544
|
-
* @param
|
|
13545
|
-
* @param nativeExtensionProvider
|
|
13546
|
-
* @param authenticationScheme
|
|
13686
|
+
* Acquires a token from native platform then redirects to the redirectUri instead of returning the response
|
|
13687
|
+
* @param {RedirectRequest} request
|
|
13688
|
+
* @param {InProgressPerformanceEvent} rootMeasurement
|
|
13547
13689
|
*/
|
|
13548
|
-
|
|
13549
|
-
logger.trace("
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
if (!nativeExtensionProvider) {
|
|
13556
|
-
logger.trace("isPlatformBrokerAvailable: Platform extension provider is not initialized, returning false");
|
|
13557
|
-
// Extension is not available
|
|
13558
|
-
return false;
|
|
13690
|
+
async acquireTokenRedirect(request, rootMeasurement) {
|
|
13691
|
+
this.logger.trace("NativeInteractionClient - acquireTokenRedirect called.");
|
|
13692
|
+
const { ...remainingParameters } = request;
|
|
13693
|
+
delete remainingParameters.onRedirectNavigate;
|
|
13694
|
+
const nativeRequest = await this.initializeNativeRequest(remainingParameters);
|
|
13695
|
+
try {
|
|
13696
|
+
await this.platformAuthProvider.sendMessage(nativeRequest);
|
|
13559
13697
|
}
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
return false;
|
|
13698
|
+
catch (e) {
|
|
13699
|
+
// Only throw fatal errors here to allow application to fallback to regular redirect. Otherwise proceed and the error will be thrown in handleRedirectPromise
|
|
13700
|
+
if (e instanceof NativeAuthError) {
|
|
13701
|
+
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
13702
|
+
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
|
|
13703
|
+
if (isFatalNativeAuthError(e)) {
|
|
13704
|
+
throw e;
|
|
13705
|
+
}
|
|
13569
13706
|
}
|
|
13570
13707
|
}
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
* @param state
|
|
13583
|
-
*/
|
|
13584
|
-
function extractBrowserRequestState(browserCrypto, state) {
|
|
13585
|
-
if (!state) {
|
|
13586
|
-
return null;
|
|
13587
|
-
}
|
|
13588
|
-
try {
|
|
13589
|
-
const requestStateObj = ProtocolUtils.parseRequestState(browserCrypto, state);
|
|
13590
|
-
return requestStateObj.libraryState.meta;
|
|
13591
|
-
}
|
|
13592
|
-
catch (e) {
|
|
13593
|
-
throw createClientAuthError(invalidState);
|
|
13594
|
-
}
|
|
13595
|
-
}
|
|
13596
|
-
|
|
13597
|
-
/*
|
|
13598
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13599
|
-
* Licensed under the MIT License.
|
|
13600
|
-
*/
|
|
13601
|
-
function deserializeResponse(responseString, responseLocation, logger) {
|
|
13602
|
-
// Deserialize hash fragment response parameters.
|
|
13603
|
-
const serverParams = getDeserializedResponse(responseString);
|
|
13604
|
-
if (!serverParams) {
|
|
13605
|
-
if (!stripLeadingHashOrQuery(responseString)) {
|
|
13606
|
-
// Hash or Query string is empty
|
|
13607
|
-
logger.error(`The request has returned to the redirectUri but a ${responseLocation} is not present. It's likely that the ${responseLocation} has been removed or the page has been redirected by code running on the redirectUri page.`);
|
|
13608
|
-
throw createBrowserAuthError(hashEmptyError);
|
|
13609
|
-
}
|
|
13610
|
-
else {
|
|
13611
|
-
logger.error(`A ${responseLocation} is present in the iframe but it does not contain known properties. It's likely that the ${responseLocation} has been replaced by code running on the redirectUri page.`);
|
|
13612
|
-
logger.errorPii(`The ${responseLocation} detected is: ${responseString}`);
|
|
13613
|
-
throw createBrowserAuthError(hashDoesNotContainKnownProperties);
|
|
13614
|
-
}
|
|
13615
|
-
}
|
|
13616
|
-
return serverParams;
|
|
13617
|
-
}
|
|
13618
|
-
/**
|
|
13619
|
-
* Returns the interaction type that the response object belongs to
|
|
13620
|
-
*/
|
|
13621
|
-
function validateInteractionType(response, browserCrypto, interactionType) {
|
|
13622
|
-
if (!response.state) {
|
|
13623
|
-
throw createBrowserAuthError(noStateInHash);
|
|
13624
|
-
}
|
|
13625
|
-
const platformStateObj = extractBrowserRequestState(browserCrypto, response.state);
|
|
13626
|
-
if (!platformStateObj) {
|
|
13627
|
-
throw createBrowserAuthError(unableToParseState);
|
|
13628
|
-
}
|
|
13629
|
-
if (platformStateObj.interactionType !== interactionType) {
|
|
13630
|
-
throw createBrowserAuthError(stateInteractionTypeMismatch);
|
|
13631
|
-
}
|
|
13632
|
-
}
|
|
13633
|
-
|
|
13634
|
-
/*
|
|
13635
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13636
|
-
* Licensed under the MIT License.
|
|
13637
|
-
*/
|
|
13638
|
-
/**
|
|
13639
|
-
* Abstract class which defines operations for a browser interaction handling class.
|
|
13640
|
-
*/
|
|
13641
|
-
class InteractionHandler {
|
|
13642
|
-
constructor(authCodeModule, storageImpl, authCodeRequest, logger, performanceClient) {
|
|
13643
|
-
this.authModule = authCodeModule;
|
|
13644
|
-
this.browserStorage = storageImpl;
|
|
13645
|
-
this.authCodeRequest = authCodeRequest;
|
|
13646
|
-
this.logger = logger;
|
|
13647
|
-
this.performanceClient = performanceClient;
|
|
13708
|
+
this.browserStorage.setTemporaryCache(TemporaryCacheKeys.NATIVE_REQUEST, JSON.stringify(nativeRequest), true);
|
|
13709
|
+
const navigationOptions = {
|
|
13710
|
+
apiId: ApiId.acquireTokenRedirect,
|
|
13711
|
+
timeout: this.config.system.redirectNavigationTimeout,
|
|
13712
|
+
noHistory: false,
|
|
13713
|
+
};
|
|
13714
|
+
const redirectUri = this.config.auth.navigateToLoginRequestUrl
|
|
13715
|
+
? window.location.href
|
|
13716
|
+
: this.getRedirectUri(request.redirectUri);
|
|
13717
|
+
rootMeasurement.end({ success: true });
|
|
13718
|
+
await this.navigationClient.navigateExternal(redirectUri, navigationOptions); // Need to treat this as external to ensure handleRedirectPromise is run again
|
|
13648
13719
|
}
|
|
13649
13720
|
/**
|
|
13650
|
-
*
|
|
13651
|
-
* @param
|
|
13721
|
+
* If the previous page called native platform for a token using redirect APIs, send the same request again and return the response
|
|
13722
|
+
* @param performanceClient {IPerformanceClient?}
|
|
13723
|
+
* @param correlationId {string?} correlation identifier
|
|
13652
13724
|
*/
|
|
13653
|
-
async
|
|
13654
|
-
this.
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
|
|
13725
|
+
async handleRedirectPromise(performanceClient, correlationId) {
|
|
13726
|
+
this.logger.trace("NativeInteractionClient - handleRedirectPromise called.");
|
|
13727
|
+
if (!this.browserStorage.isInteractionInProgress(true)) {
|
|
13728
|
+
this.logger.info("handleRedirectPromise called but there is no interaction in progress, returning null.");
|
|
13729
|
+
return null;
|
|
13658
13730
|
}
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
|
|
13662
|
-
|
|
13663
|
-
|
|
13664
|
-
|
|
13665
|
-
else {
|
|
13666
|
-
throw e;
|
|
13731
|
+
// remove prompt from the request to prevent WAM from prompting twice
|
|
13732
|
+
const cachedRequest = this.browserStorage.getCachedNativeRequest();
|
|
13733
|
+
if (!cachedRequest) {
|
|
13734
|
+
this.logger.verbose("NativeInteractionClient - handleRedirectPromise called but there is no cached request, returning null.");
|
|
13735
|
+
if (performanceClient && correlationId) {
|
|
13736
|
+
performanceClient?.addFields({ errorCode: "no_cached_request" }, correlationId);
|
|
13667
13737
|
}
|
|
13738
|
+
return null;
|
|
13668
13739
|
}
|
|
13669
|
-
|
|
13670
|
-
|
|
13671
|
-
|
|
13672
|
-
* Process auth code response from AAD
|
|
13673
|
-
* @param authCodeResponse
|
|
13674
|
-
* @param state
|
|
13675
|
-
* @param authority
|
|
13676
|
-
* @param networkModule
|
|
13677
|
-
* @returns
|
|
13678
|
-
*/
|
|
13679
|
-
async handleCodeResponseFromServer(authCodeResponse, request, validateNonce = true) {
|
|
13680
|
-
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponseFromServer, request.correlationId);
|
|
13681
|
-
this.logger.trace("InteractionHandler.handleCodeResponseFromServer called");
|
|
13682
|
-
// Assign code to request
|
|
13683
|
-
this.authCodeRequest.code = authCodeResponse.code;
|
|
13684
|
-
// Check for new cloud instance
|
|
13685
|
-
if (authCodeResponse.cloud_instance_host_name) {
|
|
13686
|
-
await invokeAsync(this.authModule.updateAuthority.bind(this.authModule), PerformanceEvents.UpdateTokenEndpointAuthority, this.logger, this.performanceClient, request.correlationId)(authCodeResponse.cloud_instance_host_name, request.correlationId);
|
|
13687
|
-
}
|
|
13688
|
-
// Nonce validation not needed when redirect not involved (e.g. hybrid spa, renewing token via rt)
|
|
13689
|
-
if (validateNonce) {
|
|
13690
|
-
// TODO: Assigning "response nonce" to "request nonce" is confusing. Refactor the function doing validation to accept request nonce directly
|
|
13691
|
-
authCodeResponse.nonce = request.nonce || undefined;
|
|
13740
|
+
const { prompt, ...request } = cachedRequest;
|
|
13741
|
+
if (prompt) {
|
|
13742
|
+
this.logger.verbose("NativeInteractionClient - handleRedirectPromise called and prompt was included in the original request, removing prompt from cached request to prevent second interaction with native broker window.");
|
|
13692
13743
|
}
|
|
13693
|
-
|
|
13694
|
-
|
|
13695
|
-
|
|
13696
|
-
this.
|
|
13744
|
+
this.browserStorage.removeItem(this.browserStorage.generateCacheKey(TemporaryCacheKeys.NATIVE_REQUEST));
|
|
13745
|
+
const reqTimestamp = nowSeconds();
|
|
13746
|
+
try {
|
|
13747
|
+
this.logger.verbose("NativeInteractionClient - handleRedirectPromise sending message to native broker.");
|
|
13748
|
+
const response = await this.platformAuthProvider.sendMessage(request);
|
|
13749
|
+
const authResult = await this.handleNativeResponse(response, request, reqTimestamp);
|
|
13750
|
+
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
13751
|
+
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
13752
|
+
return authResult;
|
|
13697
13753
|
}
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
if (ccsCred) {
|
|
13701
|
-
this.authCodeRequest.ccsCredential = ccsCred;
|
|
13702
|
-
}
|
|
13754
|
+
catch (e) {
|
|
13755
|
+
throw e;
|
|
13703
13756
|
}
|
|
13704
|
-
// Acquire token with retrieved code.
|
|
13705
|
-
const tokenResponse = (await invokeAsync(this.authModule.acquireToken.bind(this.authModule), PerformanceEvents.AuthClientAcquireToken, this.logger, this.performanceClient, request.correlationId)(this.authCodeRequest, authCodeResponse));
|
|
13706
|
-
return tokenResponse;
|
|
13707
13757
|
}
|
|
13708
13758
|
/**
|
|
13709
|
-
*
|
|
13759
|
+
* Logout from native platform via browser extension
|
|
13760
|
+
* @param request
|
|
13710
13761
|
*/
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
|
|
13714
|
-
credential: request.account.homeAccountId,
|
|
13715
|
-
type: CcsCredentialType.HOME_ACCOUNT_ID,
|
|
13716
|
-
};
|
|
13717
|
-
}
|
|
13718
|
-
else if (request.loginHint) {
|
|
13719
|
-
return {
|
|
13720
|
-
credential: request.loginHint,
|
|
13721
|
-
type: CcsCredentialType.UPN,
|
|
13722
|
-
};
|
|
13723
|
-
}
|
|
13724
|
-
return null;
|
|
13762
|
+
logout() {
|
|
13763
|
+
this.logger.trace("NativeInteractionClient - logout called.");
|
|
13764
|
+
return Promise.reject("Logout not implemented yet");
|
|
13725
13765
|
}
|
|
13726
|
-
}
|
|
13727
|
-
|
|
13728
|
-
/*
|
|
13729
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13730
|
-
* Licensed under the MIT License.
|
|
13731
|
-
*/
|
|
13732
|
-
class SilentCacheClient extends StandardInteractionClient {
|
|
13733
13766
|
/**
|
|
13734
|
-
*
|
|
13735
|
-
* @param
|
|
13767
|
+
* Transform response from native platform into AuthenticationResult object which will be returned to the end user
|
|
13768
|
+
* @param response
|
|
13769
|
+
* @param request
|
|
13770
|
+
* @param reqTimestamp
|
|
13736
13771
|
*/
|
|
13737
|
-
async
|
|
13738
|
-
this.
|
|
13739
|
-
//
|
|
13740
|
-
const
|
|
13741
|
-
const
|
|
13742
|
-
|
|
13743
|
-
|
|
13744
|
-
|
|
13745
|
-
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
13749
|
-
try {
|
|
13750
|
-
const response = await invokeAsync(silentAuthClient.acquireCachedToken.bind(silentAuthClient), PerformanceEvents.SilentFlowClientAcquireCachedToken, this.logger, this.performanceClient, silentRequest.correlationId)(silentRequest);
|
|
13751
|
-
const authResponse = response[0];
|
|
13752
|
-
this.performanceClient.addFields({
|
|
13753
|
-
fromCache: true,
|
|
13754
|
-
}, silentRequest.correlationId);
|
|
13755
|
-
return authResponse;
|
|
13772
|
+
async handleNativeResponse(response, request, reqTimestamp) {
|
|
13773
|
+
this.logger.trace("NativeInteractionClient - handleNativeResponse called.");
|
|
13774
|
+
// generate identifiers
|
|
13775
|
+
const idTokenClaims = extractTokenClaims(response.id_token, base64Decode);
|
|
13776
|
+
const homeAccountIdentifier = this.createHomeAccountIdentifier(response, idTokenClaims);
|
|
13777
|
+
const cachedhomeAccountId = this.browserStorage.getAccountInfoFilteredBy({
|
|
13778
|
+
nativeAccountId: request.accountId,
|
|
13779
|
+
})?.homeAccountId;
|
|
13780
|
+
// add exception for double brokering, please note this is temporary and will be fortified in future
|
|
13781
|
+
if (request.extraParameters?.child_client_id &&
|
|
13782
|
+
response.account.id !== request.accountId) {
|
|
13783
|
+
this.logger.info("handleNativeServerResponse: Double broker flow detected, ignoring accountId mismatch");
|
|
13756
13784
|
}
|
|
13757
|
-
|
|
13758
|
-
|
|
13759
|
-
|
|
13760
|
-
|
|
13761
|
-
}
|
|
13762
|
-
throw error;
|
|
13785
|
+
else if (homeAccountIdentifier !== cachedhomeAccountId &&
|
|
13786
|
+
response.account.id !== request.accountId) {
|
|
13787
|
+
// User switch in native broker prompt is not supported. All users must first sign in through web flow to ensure server state is in sync
|
|
13788
|
+
throw createNativeAuthError(userSwitch);
|
|
13763
13789
|
}
|
|
13790
|
+
// Get the preferred_cache domain for the given authority
|
|
13791
|
+
const authority = await this.getDiscoveredAuthority({
|
|
13792
|
+
requestAuthority: request.authority,
|
|
13793
|
+
});
|
|
13794
|
+
const baseAccount = buildAccountToCache(this.browserStorage, authority, homeAccountIdentifier, base64Decode, idTokenClaims, response.client_info, undefined, // environment
|
|
13795
|
+
idTokenClaims.tid, undefined, // auth code payload
|
|
13796
|
+
response.account.id, this.logger);
|
|
13797
|
+
// Ensure expires_in is in number format
|
|
13798
|
+
response.expires_in = Number(response.expires_in);
|
|
13799
|
+
// generate authenticationResult
|
|
13800
|
+
const result = await this.generateAuthenticationResult(response, request, idTokenClaims, baseAccount, authority.canonicalAuthority, reqTimestamp);
|
|
13801
|
+
// cache accounts and tokens in the appropriate storage
|
|
13802
|
+
await this.cacheAccount(baseAccount);
|
|
13803
|
+
await this.cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, response.access_token, result.tenantId, reqTimestamp);
|
|
13804
|
+
return result;
|
|
13764
13805
|
}
|
|
13765
13806
|
/**
|
|
13766
|
-
*
|
|
13767
|
-
* @param
|
|
13807
|
+
* creates an homeAccountIdentifier for the account
|
|
13808
|
+
* @param response
|
|
13809
|
+
* @param idTokenObj
|
|
13810
|
+
* @returns
|
|
13768
13811
|
*/
|
|
13769
|
-
|
|
13770
|
-
|
|
13771
|
-
const
|
|
13772
|
-
return
|
|
13773
|
-
}
|
|
13774
|
-
}
|
|
13775
|
-
|
|
13776
|
-
/*
|
|
13777
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13778
|
-
* Licensed under the MIT License.
|
|
13779
|
-
*/
|
|
13780
|
-
class NativeInteractionClient extends BaseInteractionClient {
|
|
13781
|
-
constructor(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, provider, accountId, nativeStorageImpl, correlationId) {
|
|
13782
|
-
super(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13783
|
-
this.apiId = apiId;
|
|
13784
|
-
this.accountId = accountId;
|
|
13785
|
-
this.nativeMessageHandler = provider;
|
|
13786
|
-
this.nativeStorageManager = nativeStorageImpl;
|
|
13787
|
-
this.silentCacheClient = new SilentCacheClient(config, this.nativeStorageManager, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13788
|
-
const extensionName = this.nativeMessageHandler.getExtensionId() ===
|
|
13789
|
-
NativeConstants.PREFERRED_EXTENSION_ID
|
|
13790
|
-
? "chrome"
|
|
13791
|
-
: this.nativeMessageHandler.getExtensionId()?.length
|
|
13792
|
-
? "unknown"
|
|
13793
|
-
: undefined;
|
|
13794
|
-
this.skus = ServerTelemetryManager.makeExtraSkuString({
|
|
13795
|
-
libraryName: BrowserConstants.MSAL_SKU,
|
|
13796
|
-
libraryVersion: version,
|
|
13797
|
-
extensionName: extensionName,
|
|
13798
|
-
extensionVersion: this.nativeMessageHandler.getExtensionVersion(),
|
|
13799
|
-
});
|
|
13812
|
+
createHomeAccountIdentifier(response, idTokenClaims) {
|
|
13813
|
+
// Save account in browser storage
|
|
13814
|
+
const homeAccountIdentifier = AccountEntity.generateHomeAccountId(response.client_info || Constants.EMPTY_STRING, AuthorityType.Default, this.logger, this.browserCrypto, idTokenClaims);
|
|
13815
|
+
return homeAccountIdentifier;
|
|
13800
13816
|
}
|
|
13801
13817
|
/**
|
|
13802
|
-
*
|
|
13803
|
-
* @param
|
|
13804
|
-
* @
|
|
13818
|
+
* Helper to generate scopes
|
|
13819
|
+
* @param response
|
|
13820
|
+
* @param request
|
|
13821
|
+
* @returns
|
|
13805
13822
|
*/
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13809
|
-
|
|
13810
|
-
};
|
|
13823
|
+
generateScopes(requestScopes, responseScopes) {
|
|
13824
|
+
return responseScopes
|
|
13825
|
+
? ScopeSet.fromString(responseScopes)
|
|
13826
|
+
: ScopeSet.fromString(requestScopes);
|
|
13811
13827
|
}
|
|
13812
13828
|
/**
|
|
13813
|
-
*
|
|
13829
|
+
* If PoP token is requesred, records the PoP token if returned from the WAM, else generates one in the browser
|
|
13814
13830
|
* @param request
|
|
13831
|
+
* @param response
|
|
13815
13832
|
*/
|
|
13816
|
-
async
|
|
13817
|
-
|
|
13818
|
-
|
|
13819
|
-
|
|
13820
|
-
|
|
13821
|
-
|
|
13822
|
-
|
|
13823
|
-
|
|
13824
|
-
|
|
13825
|
-
|
|
13826
|
-
|
|
13827
|
-
try {
|
|
13828
|
-
const result = await this.acquireTokensFromCache(this.accountId, nativeRequest);
|
|
13829
|
-
nativeATMeasurement.end({
|
|
13830
|
-
success: true,
|
|
13831
|
-
isNativeBroker: false,
|
|
13832
|
-
fromCache: true,
|
|
13833
|
-
});
|
|
13834
|
-
return result;
|
|
13835
|
-
}
|
|
13836
|
-
catch (e) {
|
|
13837
|
-
if (cacheLookupPolicy === CacheLookupPolicy.AccessToken) {
|
|
13838
|
-
this.logger.info("MSAL internal Cache does not contain tokens, return error as per cache policy");
|
|
13839
|
-
throw e;
|
|
13840
|
-
}
|
|
13841
|
-
// continue with a native call for any and all errors
|
|
13842
|
-
this.logger.info("MSAL internal Cache does not contain tokens, proceed to make a native call");
|
|
13833
|
+
async generatePopAccessToken(response, request) {
|
|
13834
|
+
if (request.tokenType === AuthenticationScheme.POP &&
|
|
13835
|
+
request.signPopToken) {
|
|
13836
|
+
/**
|
|
13837
|
+
* This code prioritizes SHR returned from the native layer. In case of error/SHR not calculated from WAM and the AT
|
|
13838
|
+
* is still received, SHR is calculated locally
|
|
13839
|
+
*/
|
|
13840
|
+
// Check if native layer returned an SHR token
|
|
13841
|
+
if (response.shr) {
|
|
13842
|
+
this.logger.trace("handleNativeServerResponse: SHR is enabled in native layer");
|
|
13843
|
+
return response.shr;
|
|
13843
13844
|
}
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
const
|
|
13847
|
-
|
|
13848
|
-
|
|
13845
|
+
// Generate SHR in msal js if WAM does not compute it when POP is enabled
|
|
13846
|
+
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto);
|
|
13847
|
+
const shrParameters = {
|
|
13848
|
+
resourceRequestMethod: request.resourceRequestMethod,
|
|
13849
|
+
resourceRequestUri: request.resourceRequestUri,
|
|
13850
|
+
shrClaims: request.shrClaims,
|
|
13851
|
+
shrNonce: request.shrNonce,
|
|
13849
13852
|
};
|
|
13850
|
-
|
|
13851
|
-
|
|
13852
|
-
|
|
13853
|
-
|
|
13854
|
-
|
|
13855
|
-
|
|
13856
|
-
isNativeBroker: true,
|
|
13857
|
-
requestId: result.requestId,
|
|
13858
|
-
});
|
|
13859
|
-
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
13860
|
-
return result;
|
|
13861
|
-
})
|
|
13862
|
-
.catch((error) => {
|
|
13863
|
-
nativeATMeasurement.end({
|
|
13864
|
-
success: false,
|
|
13865
|
-
errorCode: error.errorCode,
|
|
13866
|
-
subErrorCode: error.subError,
|
|
13867
|
-
isNativeBroker: true,
|
|
13868
|
-
});
|
|
13869
|
-
throw error;
|
|
13870
|
-
});
|
|
13871
|
-
}
|
|
13872
|
-
catch (e) {
|
|
13873
|
-
if (e instanceof NativeAuthError) {
|
|
13874
|
-
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
|
|
13853
|
+
/**
|
|
13854
|
+
* KeyID must be present in the native request from when the PoP key was generated in order for
|
|
13855
|
+
* PopTokenGenerator to query the full key for signing
|
|
13856
|
+
*/
|
|
13857
|
+
if (!request.keyId) {
|
|
13858
|
+
throw createClientAuthError(keyIdMissing);
|
|
13875
13859
|
}
|
|
13876
|
-
|
|
13860
|
+
return popTokenGenerator.signPopToken(response.access_token, request.keyId, shrParameters);
|
|
13861
|
+
}
|
|
13862
|
+
else {
|
|
13863
|
+
return response.access_token;
|
|
13877
13864
|
}
|
|
13878
13865
|
}
|
|
13879
13866
|
/**
|
|
13880
|
-
*
|
|
13867
|
+
* Generates authentication result
|
|
13868
|
+
* @param response
|
|
13881
13869
|
* @param request
|
|
13882
|
-
* @param
|
|
13883
|
-
* @
|
|
13870
|
+
* @param idTokenObj
|
|
13871
|
+
* @param accountEntity
|
|
13872
|
+
* @param authority
|
|
13873
|
+
* @param reqTimestamp
|
|
13874
|
+
* @returns
|
|
13884
13875
|
*/
|
|
13885
|
-
|
|
13886
|
-
|
|
13887
|
-
|
|
13876
|
+
async generateAuthenticationResult(response, request, idTokenClaims, accountEntity, authority, reqTimestamp) {
|
|
13877
|
+
// Add Native Broker fields to Telemetry
|
|
13878
|
+
const mats = this.addTelemetryFromNativeResponse(response.properties.MATS);
|
|
13879
|
+
// If scopes not returned in server response, use request scopes
|
|
13880
|
+
const responseScopes = this.generateScopes(request.scope, response.scope);
|
|
13881
|
+
const accountProperties = response.account.properties || {};
|
|
13882
|
+
const uid = accountProperties["UID"] ||
|
|
13883
|
+
idTokenClaims.oid ||
|
|
13884
|
+
idTokenClaims.sub ||
|
|
13885
|
+
Constants.EMPTY_STRING;
|
|
13886
|
+
const tid = accountProperties["TenantId"] ||
|
|
13887
|
+
idTokenClaims.tid ||
|
|
13888
|
+
Constants.EMPTY_STRING;
|
|
13889
|
+
const accountInfo = updateAccountTenantProfileData(accountEntity.getAccountInfo(), undefined, // tenantProfile optional
|
|
13890
|
+
idTokenClaims, response.id_token);
|
|
13891
|
+
/**
|
|
13892
|
+
* In pairwise broker flows, this check prevents the broker's native account id
|
|
13893
|
+
* from being returned over the embedded app's account id.
|
|
13894
|
+
*/
|
|
13895
|
+
if (accountInfo.nativeAccountId !== response.account.id) {
|
|
13896
|
+
accountInfo.nativeAccountId = response.account.id;
|
|
13897
|
+
}
|
|
13898
|
+
// generate PoP token as needed
|
|
13899
|
+
const responseAccessToken = await this.generatePopAccessToken(response, request);
|
|
13900
|
+
const tokenType = request.tokenType === AuthenticationScheme.POP
|
|
13901
|
+
? AuthenticationScheme.POP
|
|
13902
|
+
: AuthenticationScheme.BEARER;
|
|
13903
|
+
const result = {
|
|
13904
|
+
authority: authority,
|
|
13905
|
+
uniqueId: uid,
|
|
13906
|
+
tenantId: tid,
|
|
13907
|
+
scopes: responseScopes.asArray(),
|
|
13908
|
+
account: accountInfo,
|
|
13909
|
+
idToken: response.id_token,
|
|
13910
|
+
idTokenClaims: idTokenClaims,
|
|
13911
|
+
accessToken: responseAccessToken,
|
|
13912
|
+
fromCache: mats ? this.isResponseFromCache(mats) : false,
|
|
13913
|
+
// Request timestamp and NativeResponse expires_in are in seconds, converting to Date for AuthenticationResult
|
|
13914
|
+
expiresOn: toDateFromSeconds(reqTimestamp + response.expires_in),
|
|
13915
|
+
tokenType: tokenType,
|
|
13888
13916
|
correlationId: this.correlationId,
|
|
13889
|
-
|
|
13890
|
-
|
|
13891
|
-
forceRefresh: false,
|
|
13917
|
+
state: response.state,
|
|
13918
|
+
fromNativeBroker: true,
|
|
13892
13919
|
};
|
|
13920
|
+
return result;
|
|
13893
13921
|
}
|
|
13894
13922
|
/**
|
|
13895
|
-
*
|
|
13896
|
-
* @param
|
|
13897
|
-
* @param request
|
|
13898
|
-
* @returns authenticationResult
|
|
13923
|
+
* cache the account entity in browser storage
|
|
13924
|
+
* @param accountEntity
|
|
13899
13925
|
*/
|
|
13900
|
-
async
|
|
13901
|
-
|
|
13902
|
-
|
|
13903
|
-
|
|
13904
|
-
|
|
13905
|
-
|
|
13906
|
-
const account = this.browserStorage.getBaseAccountInfo({
|
|
13907
|
-
nativeAccountId,
|
|
13926
|
+
async cacheAccount(accountEntity) {
|
|
13927
|
+
// Store the account info and hence `nativeAccountId` in browser cache
|
|
13928
|
+
await this.browserStorage.setAccount(accountEntity, this.correlationId);
|
|
13929
|
+
// Remove any existing cached tokens for this account in browser storage
|
|
13930
|
+
this.browserStorage.removeAccountContext(accountEntity).catch((e) => {
|
|
13931
|
+
this.logger.error(`Error occurred while removing account context from browser storage. ${e}`);
|
|
13908
13932
|
});
|
|
13909
|
-
if (!account) {
|
|
13910
|
-
throw createClientAuthError(noAccountFound);
|
|
13911
|
-
}
|
|
13912
|
-
// leverage silent flow for cached tokens retrieval
|
|
13913
|
-
try {
|
|
13914
|
-
const silentRequest = this.createSilentCacheRequest(request, account);
|
|
13915
|
-
const result = await this.silentCacheClient.acquireToken(silentRequest);
|
|
13916
|
-
const fullAccount = {
|
|
13917
|
-
...account,
|
|
13918
|
-
idTokenClaims: result?.idTokenClaims,
|
|
13919
|
-
idToken: result?.idToken,
|
|
13920
|
-
};
|
|
13921
|
-
return {
|
|
13922
|
-
...result,
|
|
13923
|
-
account: fullAccount,
|
|
13924
|
-
};
|
|
13925
|
-
}
|
|
13926
|
-
catch (e) {
|
|
13927
|
-
throw e;
|
|
13928
|
-
}
|
|
13929
13933
|
}
|
|
13930
13934
|
/**
|
|
13931
|
-
*
|
|
13932
|
-
* @param
|
|
13933
|
-
* @param
|
|
13935
|
+
* Stores the access_token and id_token in inmemory storage
|
|
13936
|
+
* @param response
|
|
13937
|
+
* @param request
|
|
13938
|
+
* @param homeAccountIdentifier
|
|
13939
|
+
* @param idTokenObj
|
|
13940
|
+
* @param responseAccessToken
|
|
13941
|
+
* @param tenantId
|
|
13942
|
+
* @param reqTimestamp
|
|
13934
13943
|
*/
|
|
13935
|
-
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13944
|
+
cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, responseAccessToken, tenantId, reqTimestamp) {
|
|
13945
|
+
const cachedIdToken = createIdTokenEntity(homeAccountIdentifier, request.authority, response.id_token || "", request.clientId, idTokenClaims.tid || "");
|
|
13946
|
+
// cache accessToken in inmemory storage
|
|
13947
|
+
const expiresIn = request.tokenType === AuthenticationScheme.POP
|
|
13948
|
+
? Constants.SHR_NONCE_VALIDITY
|
|
13949
|
+
: (typeof response.expires_in === "string"
|
|
13950
|
+
? parseInt(response.expires_in, 10)
|
|
13951
|
+
: response.expires_in) || 0;
|
|
13952
|
+
const tokenExpirationSeconds = reqTimestamp + expiresIn;
|
|
13953
|
+
const responseScopes = this.generateScopes(response.scope, request.scope);
|
|
13954
|
+
const cachedAccessToken = createAccessTokenEntity(homeAccountIdentifier, request.authority, responseAccessToken, request.clientId, idTokenClaims.tid || tenantId, responseScopes.printScopes(), tokenExpirationSeconds, 0, base64Decode, undefined, request.tokenType, undefined, request.keyId);
|
|
13955
|
+
const nativeCacheRecord = {
|
|
13956
|
+
idToken: cachedIdToken,
|
|
13957
|
+
accessToken: cachedAccessToken,
|
|
13943
13958
|
};
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
|
|
13959
|
+
return this.nativeStorageManager.saveCacheRecord(nativeCacheRecord, this.correlationId, request.storeInCache);
|
|
13960
|
+
}
|
|
13961
|
+
getExpiresInValue(tokenType, expiresIn) {
|
|
13962
|
+
return tokenType === AuthenticationScheme.POP
|
|
13963
|
+
? Constants.SHR_NONCE_VALIDITY
|
|
13964
|
+
: (typeof expiresIn === "string"
|
|
13965
|
+
? parseInt(expiresIn, 10)
|
|
13966
|
+
: expiresIn) || 0;
|
|
13967
|
+
}
|
|
13968
|
+
addTelemetryFromNativeResponse(matsResponse) {
|
|
13969
|
+
const mats = this.getMATSFromResponse(matsResponse);
|
|
13970
|
+
if (!mats) {
|
|
13971
|
+
return null;
|
|
13947
13972
|
}
|
|
13948
|
-
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
: this.getRedirectUri(request.redirectUri);
|
|
13967
|
-
rootMeasurement.end({ success: true });
|
|
13968
|
-
await this.navigationClient.navigateExternal(redirectUri, navigationOptions); // Need to treat this as external to ensure handleRedirectPromise is run again
|
|
13969
|
-
}
|
|
13970
|
-
/**
|
|
13971
|
-
* If the previous page called native platform for a token using redirect APIs, send the same request again and return the response
|
|
13972
|
-
* @param performanceClient {IPerformanceClient?}
|
|
13973
|
-
* @param correlationId {string?} correlation identifier
|
|
13974
|
-
*/
|
|
13975
|
-
async handleRedirectPromise(performanceClient, correlationId) {
|
|
13976
|
-
this.logger.trace("NativeInteractionClient - handleRedirectPromise called.");
|
|
13977
|
-
if (!this.browserStorage.isInteractionInProgress(true)) {
|
|
13978
|
-
this.logger.info("handleRedirectPromise called but there is no interaction in progress, returning null.");
|
|
13979
|
-
return null;
|
|
13980
|
-
}
|
|
13981
|
-
// remove prompt from the request to prevent WAM from prompting twice
|
|
13982
|
-
const cachedRequest = this.browserStorage.getCachedNativeRequest();
|
|
13983
|
-
if (!cachedRequest) {
|
|
13984
|
-
this.logger.verbose("NativeInteractionClient - handleRedirectPromise called but there is no cached request, returning null.");
|
|
13985
|
-
if (performanceClient && correlationId) {
|
|
13986
|
-
performanceClient?.addFields({ errorCode: "no_cached_request" }, correlationId);
|
|
13987
|
-
}
|
|
13988
|
-
return null;
|
|
13989
|
-
}
|
|
13990
|
-
const { prompt, ...request } = cachedRequest;
|
|
13991
|
-
if (prompt) {
|
|
13992
|
-
this.logger.verbose("NativeInteractionClient - handleRedirectPromise called and prompt was included in the original request, removing prompt from cached request to prevent second interaction with native broker window.");
|
|
13993
|
-
}
|
|
13994
|
-
this.browserStorage.removeItem(this.browserStorage.generateCacheKey(TemporaryCacheKeys.NATIVE_REQUEST));
|
|
13995
|
-
const messageBody = {
|
|
13996
|
-
method: NativeExtensionMethod.GetToken,
|
|
13997
|
-
request: request,
|
|
13998
|
-
};
|
|
13999
|
-
const reqTimestamp = nowSeconds();
|
|
14000
|
-
try {
|
|
14001
|
-
this.logger.verbose("NativeInteractionClient - handleRedirectPromise sending message to native broker.");
|
|
14002
|
-
const response = await this.nativeMessageHandler.sendMessage(messageBody);
|
|
14003
|
-
this.validateNativeResponse(response);
|
|
14004
|
-
const result = this.handleNativeResponse(response, request, reqTimestamp);
|
|
14005
|
-
const res = await result;
|
|
14006
|
-
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
14007
|
-
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
14008
|
-
return res;
|
|
14009
|
-
}
|
|
14010
|
-
catch (e) {
|
|
14011
|
-
throw e;
|
|
14012
|
-
}
|
|
14013
|
-
}
|
|
14014
|
-
/**
|
|
14015
|
-
* Logout from native platform via browser extension
|
|
14016
|
-
* @param request
|
|
14017
|
-
*/
|
|
14018
|
-
logout() {
|
|
14019
|
-
this.logger.trace("NativeInteractionClient - logout called.");
|
|
14020
|
-
return Promise.reject("Logout not implemented yet");
|
|
14021
|
-
}
|
|
14022
|
-
/**
|
|
14023
|
-
* Transform response from native platform into AuthenticationResult object which will be returned to the end user
|
|
14024
|
-
* @param response
|
|
14025
|
-
* @param request
|
|
14026
|
-
* @param reqTimestamp
|
|
14027
|
-
*/
|
|
14028
|
-
async handleNativeResponse(response, request, reqTimestamp) {
|
|
14029
|
-
this.logger.trace("NativeInteractionClient - handleNativeResponse called.");
|
|
14030
|
-
// generate identifiers
|
|
14031
|
-
const idTokenClaims = extractTokenClaims(response.id_token, base64Decode);
|
|
14032
|
-
const homeAccountIdentifier = this.createHomeAccountIdentifier(response, idTokenClaims);
|
|
14033
|
-
const cachedhomeAccountId = this.browserStorage.getAccountInfoFilteredBy({
|
|
14034
|
-
nativeAccountId: request.accountId,
|
|
14035
|
-
})?.homeAccountId;
|
|
14036
|
-
// add exception for double brokering, please note this is temporary and will be fortified in future
|
|
14037
|
-
if (request.extraParameters?.child_client_id &&
|
|
14038
|
-
response.account.id !== request.accountId) {
|
|
14039
|
-
this.logger.info("handleNativeServerResponse: Double broker flow detected, ignoring accountId mismatch");
|
|
14040
|
-
}
|
|
14041
|
-
else if (homeAccountIdentifier !== cachedhomeAccountId &&
|
|
14042
|
-
response.account.id !== request.accountId) {
|
|
14043
|
-
// User switch in native broker prompt is not supported. All users must first sign in through web flow to ensure server state is in sync
|
|
14044
|
-
throw createNativeAuthError(userSwitch);
|
|
14045
|
-
}
|
|
14046
|
-
// Get the preferred_cache domain for the given authority
|
|
14047
|
-
const authority = await this.getDiscoveredAuthority({
|
|
14048
|
-
requestAuthority: request.authority,
|
|
14049
|
-
});
|
|
14050
|
-
const baseAccount = buildAccountToCache(this.browserStorage, authority, homeAccountIdentifier, base64Decode, idTokenClaims, response.client_info, undefined, // environment
|
|
14051
|
-
idTokenClaims.tid, undefined, // auth code payload
|
|
14052
|
-
response.account.id, this.logger);
|
|
14053
|
-
// Ensure expires_in is in number format
|
|
14054
|
-
response.expires_in = Number(response.expires_in);
|
|
14055
|
-
// generate authenticationResult
|
|
14056
|
-
const result = await this.generateAuthenticationResult(response, request, idTokenClaims, baseAccount, authority.canonicalAuthority, reqTimestamp);
|
|
14057
|
-
// cache accounts and tokens in the appropriate storage
|
|
14058
|
-
await this.cacheAccount(baseAccount);
|
|
14059
|
-
await this.cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, response.access_token, result.tenantId, reqTimestamp);
|
|
14060
|
-
return result;
|
|
13973
|
+
this.performanceClient.addFields({
|
|
13974
|
+
extensionId: this.platformAuthProvider.getExtensionId(),
|
|
13975
|
+
extensionVersion: this.platformAuthProvider.getExtensionVersion(),
|
|
13976
|
+
matsBrokerVersion: mats.broker_version,
|
|
13977
|
+
matsAccountJoinOnStart: mats.account_join_on_start,
|
|
13978
|
+
matsAccountJoinOnEnd: mats.account_join_on_end,
|
|
13979
|
+
matsDeviceJoin: mats.device_join,
|
|
13980
|
+
matsPromptBehavior: mats.prompt_behavior,
|
|
13981
|
+
matsApiErrorCode: mats.api_error_code,
|
|
13982
|
+
matsUiVisible: mats.ui_visible,
|
|
13983
|
+
matsSilentCode: mats.silent_code,
|
|
13984
|
+
matsSilentBiSubCode: mats.silent_bi_sub_code,
|
|
13985
|
+
matsSilentMessage: mats.silent_message,
|
|
13986
|
+
matsSilentStatus: mats.silent_status,
|
|
13987
|
+
matsHttpStatus: mats.http_status,
|
|
13988
|
+
matsHttpEventCount: mats.http_event_count,
|
|
13989
|
+
}, this.correlationId);
|
|
13990
|
+
return mats;
|
|
14061
13991
|
}
|
|
14062
13992
|
/**
|
|
14063
|
-
*
|
|
13993
|
+
* Gets MATS telemetry from native response
|
|
14064
13994
|
* @param response
|
|
14065
|
-
* @param idTokenObj
|
|
14066
13995
|
* @returns
|
|
14067
13996
|
*/
|
|
14068
|
-
|
|
14069
|
-
|
|
14070
|
-
|
|
14071
|
-
|
|
13997
|
+
getMATSFromResponse(matsResponse) {
|
|
13998
|
+
if (matsResponse) {
|
|
13999
|
+
try {
|
|
14000
|
+
return JSON.parse(matsResponse);
|
|
14001
|
+
}
|
|
14002
|
+
catch (e) {
|
|
14003
|
+
this.logger.error("NativeInteractionClient - Error parsing MATS telemetry, returning null instead");
|
|
14004
|
+
}
|
|
14005
|
+
}
|
|
14006
|
+
return null;
|
|
14072
14007
|
}
|
|
14073
14008
|
/**
|
|
14074
|
-
*
|
|
14009
|
+
* Returns whether or not response came from native cache
|
|
14075
14010
|
* @param response
|
|
14076
|
-
* @param request
|
|
14077
14011
|
* @returns
|
|
14078
14012
|
*/
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
|
|
14082
|
-
|
|
14013
|
+
isResponseFromCache(mats) {
|
|
14014
|
+
if (typeof mats.is_cached === "undefined") {
|
|
14015
|
+
this.logger.verbose("NativeInteractionClient - MATS telemetry does not contain field indicating if response was served from cache. Returning false.");
|
|
14016
|
+
return false;
|
|
14017
|
+
}
|
|
14018
|
+
return !!mats.is_cached;
|
|
14083
14019
|
}
|
|
14084
14020
|
/**
|
|
14085
|
-
*
|
|
14021
|
+
* Translates developer provided request object into NativeRequest object
|
|
14086
14022
|
* @param request
|
|
14087
|
-
* @param response
|
|
14088
14023
|
*/
|
|
14089
|
-
async
|
|
14090
|
-
|
|
14091
|
-
|
|
14092
|
-
|
|
14093
|
-
|
|
14094
|
-
|
|
14095
|
-
|
|
14096
|
-
|
|
14097
|
-
|
|
14098
|
-
|
|
14099
|
-
|
|
14100
|
-
|
|
14101
|
-
|
|
14102
|
-
|
|
14024
|
+
async initializeNativeRequest(request) {
|
|
14025
|
+
this.logger.trace("NativeInteractionClient - initializeNativeRequest called");
|
|
14026
|
+
const canonicalAuthority = await this.getCanonicalAuthority(request);
|
|
14027
|
+
// scopes are expected to be received by the native broker as "scope" and will be added to the request below. Other properties that should be dropped from the request to the native broker can be included in the object destructuring here.
|
|
14028
|
+
const { scopes, ...remainingProperties } = request;
|
|
14029
|
+
const scopeSet = new ScopeSet(scopes || []);
|
|
14030
|
+
scopeSet.appendScopes(OIDC_DEFAULT_SCOPES);
|
|
14031
|
+
const validatedRequest = {
|
|
14032
|
+
...remainingProperties,
|
|
14033
|
+
accountId: this.accountId,
|
|
14034
|
+
clientId: this.config.auth.clientId,
|
|
14035
|
+
authority: canonicalAuthority.urlString,
|
|
14036
|
+
scope: scopeSet.printScopes(),
|
|
14037
|
+
redirectUri: this.getRedirectUri(request.redirectUri),
|
|
14038
|
+
prompt: this.getPrompt(request.prompt),
|
|
14039
|
+
correlationId: this.correlationId,
|
|
14040
|
+
tokenType: request.authenticationScheme,
|
|
14041
|
+
windowTitleSubstring: document.title,
|
|
14042
|
+
extraParameters: {
|
|
14043
|
+
...request.extraQueryParameters,
|
|
14044
|
+
...request.tokenQueryParameters,
|
|
14045
|
+
},
|
|
14046
|
+
extendedExpiryToken: false,
|
|
14047
|
+
keyId: request.popKid,
|
|
14048
|
+
};
|
|
14049
|
+
// Check for PoP token requests: signPopToken should only be set to true if popKid is not set
|
|
14050
|
+
if (validatedRequest.signPopToken && !!request.popKid) {
|
|
14051
|
+
throw createBrowserAuthError(invalidPopTokenRequest);
|
|
14052
|
+
}
|
|
14053
|
+
this.handleExtraBrokerParams(validatedRequest);
|
|
14054
|
+
validatedRequest.extraParameters =
|
|
14055
|
+
validatedRequest.extraParameters || {};
|
|
14056
|
+
validatedRequest.extraParameters.telemetry =
|
|
14057
|
+
PlatformAuthConstants.MATS_TELEMETRY;
|
|
14058
|
+
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14059
|
+
// add POP request type
|
|
14103
14060
|
const shrParameters = {
|
|
14104
|
-
resourceRequestMethod: request.resourceRequestMethod,
|
|
14105
14061
|
resourceRequestUri: request.resourceRequestUri,
|
|
14062
|
+
resourceRequestMethod: request.resourceRequestMethod,
|
|
14106
14063
|
shrClaims: request.shrClaims,
|
|
14107
14064
|
shrNonce: request.shrNonce,
|
|
14108
14065
|
};
|
|
14109
|
-
|
|
14110
|
-
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
|
|
14114
|
-
|
|
14066
|
+
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto);
|
|
14067
|
+
// generate reqCnf if not provided in the request
|
|
14068
|
+
let reqCnfData;
|
|
14069
|
+
if (!validatedRequest.keyId) {
|
|
14070
|
+
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(shrParameters, this.logger);
|
|
14071
|
+
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14072
|
+
validatedRequest.keyId = generatedReqCnfData.kid;
|
|
14073
|
+
validatedRequest.signPopToken = true;
|
|
14115
14074
|
}
|
|
14116
|
-
|
|
14075
|
+
else {
|
|
14076
|
+
reqCnfData = this.browserCrypto.base64UrlEncode(JSON.stringify({ kid: validatedRequest.keyId }));
|
|
14077
|
+
validatedRequest.signPopToken = false;
|
|
14078
|
+
}
|
|
14079
|
+
// SPAs require whole string to be passed to broker
|
|
14080
|
+
validatedRequest.reqCnf = reqCnfData;
|
|
14117
14081
|
}
|
|
14118
|
-
|
|
14119
|
-
|
|
14082
|
+
this.addRequestSKUs(validatedRequest);
|
|
14083
|
+
return validatedRequest;
|
|
14084
|
+
}
|
|
14085
|
+
async getCanonicalAuthority(request) {
|
|
14086
|
+
const requestAuthority = request.authority || this.config.auth.authority;
|
|
14087
|
+
if (request.account) {
|
|
14088
|
+
// validate authority
|
|
14089
|
+
await this.getDiscoveredAuthority({
|
|
14090
|
+
requestAuthority,
|
|
14091
|
+
requestAzureCloudOptions: request.azureCloudOptions,
|
|
14092
|
+
account: request.account,
|
|
14093
|
+
});
|
|
14094
|
+
}
|
|
14095
|
+
const canonicalAuthority = new UrlString(requestAuthority);
|
|
14096
|
+
canonicalAuthority.validateAsUri();
|
|
14097
|
+
return canonicalAuthority;
|
|
14098
|
+
}
|
|
14099
|
+
getPrompt(prompt) {
|
|
14100
|
+
// If request is silent, prompt is always none
|
|
14101
|
+
switch (this.apiId) {
|
|
14102
|
+
case ApiId.ssoSilent:
|
|
14103
|
+
case ApiId.acquireTokenSilent_silentFlow:
|
|
14104
|
+
this.logger.trace("initializeNativeRequest: silent request sets prompt to none");
|
|
14105
|
+
return PromptValue.NONE;
|
|
14106
|
+
}
|
|
14107
|
+
// Prompt not provided, request may proceed and native broker decides if it needs to prompt
|
|
14108
|
+
if (!prompt) {
|
|
14109
|
+
this.logger.trace("initializeNativeRequest: prompt was not provided");
|
|
14110
|
+
return undefined;
|
|
14111
|
+
}
|
|
14112
|
+
// If request is interactive, check if prompt provided is allowed to go directly to native broker
|
|
14113
|
+
switch (prompt) {
|
|
14114
|
+
case PromptValue.NONE:
|
|
14115
|
+
case PromptValue.CONSENT:
|
|
14116
|
+
case PromptValue.LOGIN:
|
|
14117
|
+
this.logger.trace("initializeNativeRequest: prompt is compatible with native flow");
|
|
14118
|
+
return prompt;
|
|
14119
|
+
default:
|
|
14120
|
+
this.logger.trace(`initializeNativeRequest: prompt = ${prompt} is not compatible with native flow`);
|
|
14121
|
+
throw createBrowserAuthError(nativePromptNotSupported);
|
|
14120
14122
|
}
|
|
14121
14123
|
}
|
|
14122
14124
|
/**
|
|
14123
|
-
*
|
|
14124
|
-
* @param
|
|
14125
|
-
* @
|
|
14126
|
-
* @param idTokenObj
|
|
14127
|
-
* @param accountEntity
|
|
14128
|
-
* @param authority
|
|
14129
|
-
* @param reqTimestamp
|
|
14130
|
-
* @returns
|
|
14125
|
+
* Handles extra broker request parameters
|
|
14126
|
+
* @param request {PlatformAuthRequest}
|
|
14127
|
+
* @private
|
|
14131
14128
|
*/
|
|
14132
|
-
|
|
14133
|
-
|
|
14134
|
-
|
|
14135
|
-
|
|
14136
|
-
|
|
14137
|
-
|
|
14138
|
-
|
|
14139
|
-
const accountProperties = response.account.properties || {};
|
|
14140
|
-
const uid = accountProperties["UID"] ||
|
|
14141
|
-
idTokenClaims.oid ||
|
|
14142
|
-
idTokenClaims.sub ||
|
|
14143
|
-
Constants.EMPTY_STRING;
|
|
14144
|
-
const tid = accountProperties["TenantId"] ||
|
|
14145
|
-
idTokenClaims.tid ||
|
|
14146
|
-
Constants.EMPTY_STRING;
|
|
14147
|
-
const accountInfo = updateAccountTenantProfileData(accountEntity.getAccountInfo(), undefined, // tenantProfile optional
|
|
14148
|
-
idTokenClaims, response.id_token);
|
|
14149
|
-
/**
|
|
14150
|
-
* In pairwise broker flows, this check prevents the broker's native account id
|
|
14151
|
-
* from being returned over the embedded app's account id.
|
|
14152
|
-
*/
|
|
14153
|
-
if (accountInfo.nativeAccountId !== response.account.id) {
|
|
14154
|
-
accountInfo.nativeAccountId = response.account.id;
|
|
14129
|
+
handleExtraBrokerParams(request) {
|
|
14130
|
+
const hasExtraBrokerParams = request.extraParameters &&
|
|
14131
|
+
request.extraParameters.hasOwnProperty(BROKER_CLIENT_ID) &&
|
|
14132
|
+
request.extraParameters.hasOwnProperty(BROKER_REDIRECT_URI) &&
|
|
14133
|
+
request.extraParameters.hasOwnProperty(CLIENT_ID);
|
|
14134
|
+
if (!request.embeddedClientId && !hasExtraBrokerParams) {
|
|
14135
|
+
return;
|
|
14155
14136
|
}
|
|
14156
|
-
|
|
14157
|
-
const
|
|
14158
|
-
|
|
14159
|
-
|
|
14160
|
-
|
|
14161
|
-
|
|
14162
|
-
|
|
14163
|
-
|
|
14164
|
-
|
|
14165
|
-
|
|
14166
|
-
|
|
14167
|
-
|
|
14168
|
-
|
|
14169
|
-
|
|
14170
|
-
|
|
14171
|
-
// Request timestamp and NativeResponse expires_in are in seconds, converting to Date for AuthenticationResult
|
|
14172
|
-
expiresOn: toDateFromSeconds(reqTimestamp + response.expires_in),
|
|
14173
|
-
tokenType: tokenType,
|
|
14174
|
-
correlationId: this.correlationId,
|
|
14175
|
-
state: response.state,
|
|
14176
|
-
fromNativeBroker: true,
|
|
14137
|
+
let child_client_id = "";
|
|
14138
|
+
const child_redirect_uri = request.redirectUri;
|
|
14139
|
+
if (request.embeddedClientId) {
|
|
14140
|
+
request.redirectUri = this.config.auth.redirectUri;
|
|
14141
|
+
child_client_id = request.embeddedClientId;
|
|
14142
|
+
}
|
|
14143
|
+
else if (request.extraParameters) {
|
|
14144
|
+
request.redirectUri =
|
|
14145
|
+
request.extraParameters[BROKER_REDIRECT_URI];
|
|
14146
|
+
child_client_id =
|
|
14147
|
+
request.extraParameters[CLIENT_ID];
|
|
14148
|
+
}
|
|
14149
|
+
request.extraParameters = {
|
|
14150
|
+
child_client_id,
|
|
14151
|
+
child_redirect_uri,
|
|
14177
14152
|
};
|
|
14178
|
-
|
|
14153
|
+
this.performanceClient?.addFields({
|
|
14154
|
+
embeddedClientId: child_client_id,
|
|
14155
|
+
embeddedRedirectUri: child_redirect_uri,
|
|
14156
|
+
}, request.correlationId);
|
|
14157
|
+
}
|
|
14158
|
+
}
|
|
14159
|
+
|
|
14160
|
+
/*
|
|
14161
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14162
|
+
* Licensed under the MIT License.
|
|
14163
|
+
*/
|
|
14164
|
+
/**
|
|
14165
|
+
* Returns map of parameters that are applicable to all calls to /authorize whether using PKCE or EAR
|
|
14166
|
+
* @param config
|
|
14167
|
+
* @param authority
|
|
14168
|
+
* @param request
|
|
14169
|
+
* @param logger
|
|
14170
|
+
* @param performanceClient
|
|
14171
|
+
* @returns
|
|
14172
|
+
*/
|
|
14173
|
+
async function getStandardParameters(config, authority, request, logger, performanceClient) {
|
|
14174
|
+
const parameters = getStandardAuthorizeRequestParameters({ ...config.auth, authority: authority }, request, logger, performanceClient);
|
|
14175
|
+
addLibraryInfo(parameters, {
|
|
14176
|
+
sku: BrowserConstants.MSAL_SKU,
|
|
14177
|
+
version: version,
|
|
14178
|
+
os: "",
|
|
14179
|
+
cpu: "",
|
|
14180
|
+
});
|
|
14181
|
+
if (config.auth.protocolMode !== ProtocolMode.OIDC) {
|
|
14182
|
+
addApplicationTelemetry(parameters, config.telemetry.application);
|
|
14183
|
+
}
|
|
14184
|
+
if (request.platformBroker) {
|
|
14185
|
+
// signal ests that this is a WAM call
|
|
14186
|
+
addNativeBroker(parameters);
|
|
14187
|
+
// pass the req_cnf for POP
|
|
14188
|
+
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14189
|
+
const cryptoOps = new CryptoOps(logger, performanceClient);
|
|
14190
|
+
const popTokenGenerator = new PopTokenGenerator(cryptoOps);
|
|
14191
|
+
// req_cnf is always sent as a string for SPAs
|
|
14192
|
+
let reqCnfData;
|
|
14193
|
+
if (!request.popKid) {
|
|
14194
|
+
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, logger, performanceClient, request.correlationId)(request, logger);
|
|
14195
|
+
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14196
|
+
}
|
|
14197
|
+
else {
|
|
14198
|
+
reqCnfData = cryptoOps.encodeKid(request.popKid);
|
|
14199
|
+
}
|
|
14200
|
+
addPopToken(parameters, reqCnfData);
|
|
14201
|
+
}
|
|
14202
|
+
}
|
|
14203
|
+
instrumentBrokerParams(parameters, request.correlationId, performanceClient);
|
|
14204
|
+
return parameters;
|
|
14205
|
+
}
|
|
14206
|
+
/**
|
|
14207
|
+
* Gets the full /authorize URL with request parameters when using Auth Code + PKCE
|
|
14208
|
+
* @param config
|
|
14209
|
+
* @param authority
|
|
14210
|
+
* @param request
|
|
14211
|
+
* @param logger
|
|
14212
|
+
* @param performanceClient
|
|
14213
|
+
* @returns
|
|
14214
|
+
*/
|
|
14215
|
+
async function getAuthCodeRequestUrl(config, authority, request, logger, performanceClient) {
|
|
14216
|
+
if (!request.codeChallenge) {
|
|
14217
|
+
throw createClientConfigurationError(pkceParamsMissing);
|
|
14218
|
+
}
|
|
14219
|
+
const parameters = await invokeAsync(getStandardParameters, PerformanceEvents.GetStandardParams, logger, performanceClient, request.correlationId)(config, authority, request, logger, performanceClient);
|
|
14220
|
+
addResponseType(parameters, OAuthResponseType.CODE);
|
|
14221
|
+
addCodeChallengeParams(parameters, request.codeChallenge, Constants.S256_CODE_CHALLENGE_METHOD);
|
|
14222
|
+
addExtraQueryParameters(parameters, request.extraQueryParameters || {});
|
|
14223
|
+
return getAuthorizeUrl(authority, parameters, config.auth.encodeExtraQueryParams, request.extraQueryParameters);
|
|
14224
|
+
}
|
|
14225
|
+
/**
|
|
14226
|
+
* Gets the form that will be posted to /authorize with request parameters when using EAR
|
|
14227
|
+
*/
|
|
14228
|
+
async function getEARForm(frame, config, authority, request, logger, performanceClient) {
|
|
14229
|
+
if (!request.earJwk) {
|
|
14230
|
+
throw createBrowserAuthError(earJwkEmpty);
|
|
14231
|
+
}
|
|
14232
|
+
const parameters = await getStandardParameters(config, authority, request, logger, performanceClient);
|
|
14233
|
+
addResponseType(parameters, OAuthResponseType.IDTOKEN_TOKEN_REFRESHTOKEN);
|
|
14234
|
+
addEARParameters(parameters, request.earJwk);
|
|
14235
|
+
const queryParams = new Map();
|
|
14236
|
+
addExtraQueryParameters(queryParams, request.extraQueryParameters || {});
|
|
14237
|
+
const url = getAuthorizeUrl(authority, queryParams, config.auth.encodeExtraQueryParams, request.extraQueryParameters);
|
|
14238
|
+
return createForm(frame, url, parameters);
|
|
14239
|
+
}
|
|
14240
|
+
/**
|
|
14241
|
+
* Creates form element in the provided document with auth parameters in the post body
|
|
14242
|
+
* @param frame
|
|
14243
|
+
* @param authorizeUrl
|
|
14244
|
+
* @param parameters
|
|
14245
|
+
* @returns
|
|
14246
|
+
*/
|
|
14247
|
+
function createForm(frame, authorizeUrl, parameters) {
|
|
14248
|
+
const form = frame.createElement("form");
|
|
14249
|
+
form.method = "post";
|
|
14250
|
+
form.action = authorizeUrl;
|
|
14251
|
+
parameters.forEach((value, key) => {
|
|
14252
|
+
const param = frame.createElement("input");
|
|
14253
|
+
param.hidden = true;
|
|
14254
|
+
param.name = key;
|
|
14255
|
+
param.value = value;
|
|
14256
|
+
form.appendChild(param);
|
|
14257
|
+
});
|
|
14258
|
+
frame.body.appendChild(form);
|
|
14259
|
+
return form;
|
|
14260
|
+
}
|
|
14261
|
+
/**
|
|
14262
|
+
* Response handler when server returns accountId on the /authorize request
|
|
14263
|
+
* @param request
|
|
14264
|
+
* @param accountId
|
|
14265
|
+
* @param apiId
|
|
14266
|
+
* @param config
|
|
14267
|
+
* @param browserStorage
|
|
14268
|
+
* @param nativeStorage
|
|
14269
|
+
* @param eventHandler
|
|
14270
|
+
* @param logger
|
|
14271
|
+
* @param performanceClient
|
|
14272
|
+
* @param nativeMessageHandler
|
|
14273
|
+
* @returns
|
|
14274
|
+
*/
|
|
14275
|
+
async function handleResponsePlatformBroker(request, accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider) {
|
|
14276
|
+
logger.verbose("Account id found, calling WAM for token");
|
|
14277
|
+
if (!platformAuthProvider) {
|
|
14278
|
+
throw createBrowserAuthError(nativeConnectionNotEstablished);
|
|
14279
|
+
}
|
|
14280
|
+
const browserCrypto = new CryptoOps(logger, performanceClient);
|
|
14281
|
+
const nativeInteractionClient = new PlatformAuthInteractionClient(config, browserStorage, browserCrypto, logger, eventHandler, config.system.navigationClient, apiId, performanceClient, platformAuthProvider, accountId, nativeStorage, request.correlationId);
|
|
14282
|
+
const { userRequestState } = ProtocolUtils.parseRequestState(browserCrypto, request.state);
|
|
14283
|
+
return invokeAsync(nativeInteractionClient.acquireToken.bind(nativeInteractionClient), PerformanceEvents.NativeInteractionClientAcquireToken, logger, performanceClient, request.correlationId)({
|
|
14284
|
+
...request,
|
|
14285
|
+
state: userRequestState,
|
|
14286
|
+
prompt: undefined, // Server should handle the prompt, ideally native broker can do this part silently
|
|
14287
|
+
});
|
|
14288
|
+
}
|
|
14289
|
+
/**
|
|
14290
|
+
* Response handler when server returns code on the /authorize request
|
|
14291
|
+
* @param request
|
|
14292
|
+
* @param response
|
|
14293
|
+
* @param codeVerifier
|
|
14294
|
+
* @param authClient
|
|
14295
|
+
* @param browserStorage
|
|
14296
|
+
* @param logger
|
|
14297
|
+
* @param performanceClient
|
|
14298
|
+
* @returns
|
|
14299
|
+
*/
|
|
14300
|
+
async function handleResponseCode(request, response, codeVerifier, apiId, config, authClient, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider) {
|
|
14301
|
+
// Remove throttle if it exists
|
|
14302
|
+
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14303
|
+
if (response.accountId) {
|
|
14304
|
+
return invokeAsync(handleResponsePlatformBroker, PerformanceEvents.HandleResponsePlatformBroker, logger, performanceClient, request.correlationId)(request, response.accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider);
|
|
14305
|
+
}
|
|
14306
|
+
const authCodeRequest = {
|
|
14307
|
+
...request,
|
|
14308
|
+
code: response.code || "",
|
|
14309
|
+
codeVerifier: codeVerifier,
|
|
14310
|
+
};
|
|
14311
|
+
// Create popup interaction handler.
|
|
14312
|
+
const interactionHandler = new InteractionHandler(authClient, browserStorage, authCodeRequest, logger, performanceClient);
|
|
14313
|
+
// Handle response from hash string.
|
|
14314
|
+
const result = await invokeAsync(interactionHandler.handleCodeResponse.bind(interactionHandler), PerformanceEvents.HandleCodeResponse, logger, performanceClient, request.correlationId)(response, request);
|
|
14315
|
+
return result;
|
|
14316
|
+
}
|
|
14317
|
+
/**
|
|
14318
|
+
* Response handler when server returns ear_jwe on the /authorize request
|
|
14319
|
+
* @param request
|
|
14320
|
+
* @param response
|
|
14321
|
+
* @param apiId
|
|
14322
|
+
* @param config
|
|
14323
|
+
* @param authority
|
|
14324
|
+
* @param browserStorage
|
|
14325
|
+
* @param nativeStorage
|
|
14326
|
+
* @param eventHandler
|
|
14327
|
+
* @param logger
|
|
14328
|
+
* @param performanceClient
|
|
14329
|
+
* @param nativeMessageHandler
|
|
14330
|
+
* @returns
|
|
14331
|
+
*/
|
|
14332
|
+
async function handleResponseEAR(request, response, apiId, config, authority, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider) {
|
|
14333
|
+
// Remove throttle if it exists
|
|
14334
|
+
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14335
|
+
// Validate state & check response for errors
|
|
14336
|
+
validateAuthorizationResponse(response, request.state);
|
|
14337
|
+
if (!response.ear_jwe) {
|
|
14338
|
+
throw createBrowserAuthError(earJweEmpty);
|
|
14339
|
+
}
|
|
14340
|
+
if (!request.earJwk) {
|
|
14341
|
+
throw createBrowserAuthError(earJwkEmpty);
|
|
14342
|
+
}
|
|
14343
|
+
const decryptedData = JSON.parse(await invokeAsync(decryptEarResponse, PerformanceEvents.DecryptEarResponse, logger, performanceClient, request.correlationId)(request.earJwk, response.ear_jwe));
|
|
14344
|
+
if (decryptedData.accountId) {
|
|
14345
|
+
return invokeAsync(handleResponsePlatformBroker, PerformanceEvents.HandleResponsePlatformBroker, logger, performanceClient, request.correlationId)(request, decryptedData.accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider);
|
|
14346
|
+
}
|
|
14347
|
+
const responseHandler = new ResponseHandler(config.auth.clientId, browserStorage, new CryptoOps(logger, performanceClient), logger, null, null, performanceClient);
|
|
14348
|
+
// Validate response. This function throws a server error if an error is returned by the server.
|
|
14349
|
+
responseHandler.validateTokenResponse(decryptedData);
|
|
14350
|
+
// Temporary until response handler is refactored to be more flow agnostic.
|
|
14351
|
+
const additionalData = {
|
|
14352
|
+
code: "",
|
|
14353
|
+
state: request.state,
|
|
14354
|
+
nonce: request.nonce,
|
|
14355
|
+
client_info: decryptedData.client_info,
|
|
14356
|
+
cloud_graph_host_name: decryptedData.cloud_graph_host_name,
|
|
14357
|
+
cloud_instance_host_name: decryptedData.cloud_instance_host_name,
|
|
14358
|
+
cloud_instance_name: decryptedData.cloud_instance_name,
|
|
14359
|
+
msgraph_host: decryptedData.msgraph_host,
|
|
14360
|
+
};
|
|
14361
|
+
return (await invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), PerformanceEvents.HandleServerTokenResponse, logger, performanceClient, request.correlationId)(decryptedData, authority, nowSeconds(), request, additionalData, undefined, undefined, undefined, undefined));
|
|
14362
|
+
}
|
|
14363
|
+
|
|
14364
|
+
/*
|
|
14365
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14366
|
+
* Licensed under the MIT License.
|
|
14367
|
+
*/
|
|
14368
|
+
// Constant byte array length
|
|
14369
|
+
const RANDOM_BYTE_ARR_LENGTH = 32;
|
|
14370
|
+
/**
|
|
14371
|
+
* This file defines APIs to generate PKCE codes and code verifiers.
|
|
14372
|
+
*/
|
|
14373
|
+
/**
|
|
14374
|
+
* Generates PKCE Codes. See the RFC for more information: https://tools.ietf.org/html/rfc7636
|
|
14375
|
+
*/
|
|
14376
|
+
async function generatePkceCodes(performanceClient, logger, correlationId) {
|
|
14377
|
+
performanceClient.addQueueMeasurement(PerformanceEvents.GeneratePkceCodes, correlationId);
|
|
14378
|
+
const codeVerifier = invoke(generateCodeVerifier, PerformanceEvents.GenerateCodeVerifier, logger, performanceClient, correlationId)(performanceClient, logger, correlationId);
|
|
14379
|
+
const codeChallenge = await invokeAsync(generateCodeChallengeFromVerifier, PerformanceEvents.GenerateCodeChallengeFromVerifier, logger, performanceClient, correlationId)(codeVerifier, performanceClient, logger, correlationId);
|
|
14380
|
+
return {
|
|
14381
|
+
verifier: codeVerifier,
|
|
14382
|
+
challenge: codeChallenge,
|
|
14383
|
+
};
|
|
14384
|
+
}
|
|
14385
|
+
/**
|
|
14386
|
+
* Generates a random 32 byte buffer and returns the base64
|
|
14387
|
+
* encoded string to be used as a PKCE Code Verifier
|
|
14388
|
+
*/
|
|
14389
|
+
function generateCodeVerifier(performanceClient, logger, correlationId) {
|
|
14390
|
+
try {
|
|
14391
|
+
// Generate random values as utf-8
|
|
14392
|
+
const buffer = new Uint8Array(RANDOM_BYTE_ARR_LENGTH);
|
|
14393
|
+
invoke(getRandomValues, PerformanceEvents.GetRandomValues, logger, performanceClient, correlationId)(buffer);
|
|
14394
|
+
// encode verifier as base64
|
|
14395
|
+
const pkceCodeVerifierB64 = urlEncodeArr(buffer);
|
|
14396
|
+
return pkceCodeVerifierB64;
|
|
14397
|
+
}
|
|
14398
|
+
catch (e) {
|
|
14399
|
+
throw createBrowserAuthError(pkceNotCreated);
|
|
14400
|
+
}
|
|
14401
|
+
}
|
|
14402
|
+
/**
|
|
14403
|
+
* Creates a base64 encoded PKCE Code Challenge string from the
|
|
14404
|
+
* hash created from the PKCE Code Verifier supplied
|
|
14405
|
+
*/
|
|
14406
|
+
async function generateCodeChallengeFromVerifier(pkceCodeVerifier, performanceClient, logger, correlationId) {
|
|
14407
|
+
performanceClient.addQueueMeasurement(PerformanceEvents.GenerateCodeChallengeFromVerifier, correlationId);
|
|
14408
|
+
try {
|
|
14409
|
+
// hashed verifier
|
|
14410
|
+
const pkceHashedCodeVerifier = await invokeAsync(sha256Digest, PerformanceEvents.Sha256Digest, logger, performanceClient, correlationId)(pkceCodeVerifier, performanceClient, correlationId);
|
|
14411
|
+
// encode hash as base64
|
|
14412
|
+
return urlEncodeArr(new Uint8Array(pkceHashedCodeVerifier));
|
|
14413
|
+
}
|
|
14414
|
+
catch (e) {
|
|
14415
|
+
throw createBrowserAuthError(pkceNotCreated);
|
|
14416
|
+
}
|
|
14417
|
+
}
|
|
14418
|
+
|
|
14419
|
+
/*
|
|
14420
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14421
|
+
* Licensed under the MIT License.
|
|
14422
|
+
*/
|
|
14423
|
+
class PlatformAuthExtensionHandler {
|
|
14424
|
+
constructor(logger, handshakeTimeoutMs, performanceClient, extensionId) {
|
|
14425
|
+
this.logger = logger;
|
|
14426
|
+
this.handshakeTimeoutMs = handshakeTimeoutMs;
|
|
14427
|
+
this.extensionId = extensionId;
|
|
14428
|
+
this.resolvers = new Map(); // Used for non-handshake messages
|
|
14429
|
+
this.handshakeResolvers = new Map(); // Used for handshake messages
|
|
14430
|
+
this.messageChannel = new MessageChannel();
|
|
14431
|
+
this.windowListener = this.onWindowMessage.bind(this); // Window event callback doesn't have access to 'this' unless it's bound
|
|
14432
|
+
this.performanceClient = performanceClient;
|
|
14433
|
+
this.handshakeEvent = performanceClient.startMeasurement(PerformanceEvents.NativeMessageHandlerHandshake);
|
|
14434
|
+
this.platformAuthType =
|
|
14435
|
+
PlatformAuthConstants.PLATFORM_EXTENSION_PROVIDER;
|
|
14179
14436
|
}
|
|
14180
14437
|
/**
|
|
14181
|
-
*
|
|
14182
|
-
* @param
|
|
14438
|
+
* Sends a given message to the extension and resolves with the extension response
|
|
14439
|
+
* @param request
|
|
14183
14440
|
*/
|
|
14184
|
-
async
|
|
14185
|
-
|
|
14186
|
-
|
|
14187
|
-
|
|
14188
|
-
|
|
14189
|
-
|
|
14441
|
+
async sendMessage(request) {
|
|
14442
|
+
this.logger.trace(this.platformAuthType + " - sendMessage called.");
|
|
14443
|
+
// fall back to native calls
|
|
14444
|
+
const messageBody = {
|
|
14445
|
+
method: NativeExtensionMethod.GetToken,
|
|
14446
|
+
request: request,
|
|
14447
|
+
};
|
|
14448
|
+
const req = {
|
|
14449
|
+
channel: PlatformAuthConstants.CHANNEL_ID,
|
|
14450
|
+
extensionId: this.extensionId,
|
|
14451
|
+
responseId: createNewGuid(),
|
|
14452
|
+
body: messageBody,
|
|
14453
|
+
};
|
|
14454
|
+
this.logger.trace(this.platformAuthType + " - Sending request to browser extension");
|
|
14455
|
+
this.logger.tracePii(this.platformAuthType +
|
|
14456
|
+
` - Sending request to browser extension: ${JSON.stringify(req)}`);
|
|
14457
|
+
this.messageChannel.port1.postMessage(req);
|
|
14458
|
+
const response = await new Promise((resolve, reject) => {
|
|
14459
|
+
this.resolvers.set(req.responseId, { resolve, reject });
|
|
14190
14460
|
});
|
|
14461
|
+
const validatedResponse = this.validatePlatformBrokerResponse(response);
|
|
14462
|
+
return validatedResponse;
|
|
14191
14463
|
}
|
|
14192
14464
|
/**
|
|
14193
|
-
*
|
|
14194
|
-
* @param
|
|
14195
|
-
* @param
|
|
14196
|
-
* @param
|
|
14197
|
-
* @param
|
|
14198
|
-
* @param responseAccessToken
|
|
14199
|
-
* @param tenantId
|
|
14200
|
-
* @param reqTimestamp
|
|
14465
|
+
* Returns an instance of the MessageHandler that has successfully established a connection with an extension
|
|
14466
|
+
* @param {Logger} logger
|
|
14467
|
+
* @param {number} handshakeTimeoutMs
|
|
14468
|
+
* @param {IPerformanceClient} performanceClient
|
|
14469
|
+
* @param {ICrypto} crypto
|
|
14201
14470
|
*/
|
|
14202
|
-
|
|
14203
|
-
|
|
14204
|
-
|
|
14205
|
-
|
|
14206
|
-
|
|
14207
|
-
|
|
14208
|
-
|
|
14209
|
-
|
|
14210
|
-
|
|
14211
|
-
|
|
14212
|
-
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14471
|
+
static async createProvider(logger, handshakeTimeoutMs, performanceClient) {
|
|
14472
|
+
logger.trace("PlatformAuthExtensionHandler - createProvider called.");
|
|
14473
|
+
try {
|
|
14474
|
+
const preferredProvider = new PlatformAuthExtensionHandler(logger, handshakeTimeoutMs, performanceClient, PlatformAuthConstants.PREFERRED_EXTENSION_ID);
|
|
14475
|
+
await preferredProvider.sendHandshakeRequest();
|
|
14476
|
+
return preferredProvider;
|
|
14477
|
+
}
|
|
14478
|
+
catch (e) {
|
|
14479
|
+
// If preferred extension fails for whatever reason, fallback to using any installed extension
|
|
14480
|
+
const backupProvider = new PlatformAuthExtensionHandler(logger, handshakeTimeoutMs, performanceClient);
|
|
14481
|
+
await backupProvider.sendHandshakeRequest();
|
|
14482
|
+
return backupProvider;
|
|
14483
|
+
}
|
|
14484
|
+
}
|
|
14485
|
+
/**
|
|
14486
|
+
* Send handshake request helper.
|
|
14487
|
+
*/
|
|
14488
|
+
async sendHandshakeRequest() {
|
|
14489
|
+
this.logger.trace(this.platformAuthType + " - sendHandshakeRequest called.");
|
|
14490
|
+
// Register this event listener before sending handshake
|
|
14491
|
+
window.addEventListener("message", this.windowListener, false); // false is important, because content script message processing should work first
|
|
14492
|
+
const req = {
|
|
14493
|
+
channel: PlatformAuthConstants.CHANNEL_ID,
|
|
14494
|
+
extensionId: this.extensionId,
|
|
14495
|
+
responseId: createNewGuid(),
|
|
14496
|
+
body: {
|
|
14497
|
+
method: NativeExtensionMethod.HandshakeRequest,
|
|
14498
|
+
},
|
|
14216
14499
|
};
|
|
14217
|
-
|
|
14500
|
+
this.handshakeEvent.add({
|
|
14501
|
+
extensionId: this.extensionId,
|
|
14502
|
+
extensionHandshakeTimeoutMs: this.handshakeTimeoutMs,
|
|
14503
|
+
});
|
|
14504
|
+
this.messageChannel.port1.onmessage = (event) => {
|
|
14505
|
+
this.onChannelMessage(event);
|
|
14506
|
+
};
|
|
14507
|
+
window.postMessage(req, window.origin, [this.messageChannel.port2]);
|
|
14508
|
+
return new Promise((resolve, reject) => {
|
|
14509
|
+
this.handshakeResolvers.set(req.responseId, { resolve, reject });
|
|
14510
|
+
this.timeoutId = window.setTimeout(() => {
|
|
14511
|
+
/*
|
|
14512
|
+
* Throw an error if neither HandshakeResponse nor original Handshake request are received in a reasonable timeframe.
|
|
14513
|
+
* This typically suggests an event handler stopped propagation of the Handshake request but did not respond to it on the MessageChannel port
|
|
14514
|
+
*/
|
|
14515
|
+
window.removeEventListener("message", this.windowListener, false);
|
|
14516
|
+
this.messageChannel.port1.close();
|
|
14517
|
+
this.messageChannel.port2.close();
|
|
14518
|
+
this.handshakeEvent.end({
|
|
14519
|
+
extensionHandshakeTimedOut: true,
|
|
14520
|
+
success: false,
|
|
14521
|
+
});
|
|
14522
|
+
reject(createBrowserAuthError(nativeHandshakeTimeout));
|
|
14523
|
+
this.handshakeResolvers.delete(req.responseId);
|
|
14524
|
+
}, this.handshakeTimeoutMs); // Use a reasonable timeout in milliseconds here
|
|
14525
|
+
});
|
|
14218
14526
|
}
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14222
|
-
|
|
14527
|
+
/**
|
|
14528
|
+
* Invoked when a message is posted to the window. If a handshake request is received it means the extension is not installed.
|
|
14529
|
+
* @param event
|
|
14530
|
+
*/
|
|
14531
|
+
onWindowMessage(event) {
|
|
14532
|
+
this.logger.trace(this.platformAuthType + " - onWindowMessage called");
|
|
14533
|
+
// We only accept messages from ourselves
|
|
14534
|
+
if (event.source !== window) {
|
|
14535
|
+
return;
|
|
14536
|
+
}
|
|
14537
|
+
const request = event.data;
|
|
14538
|
+
if (!request.channel ||
|
|
14539
|
+
request.channel !== PlatformAuthConstants.CHANNEL_ID) {
|
|
14540
|
+
return;
|
|
14541
|
+
}
|
|
14542
|
+
if (request.extensionId && request.extensionId !== this.extensionId) {
|
|
14543
|
+
return;
|
|
14544
|
+
}
|
|
14545
|
+
if (request.body.method === NativeExtensionMethod.HandshakeRequest) {
|
|
14546
|
+
const handshakeResolver = this.handshakeResolvers.get(request.responseId);
|
|
14547
|
+
/*
|
|
14548
|
+
* Filter out responses with no matched resolvers sooner to keep channel ports open while waiting for
|
|
14549
|
+
* the proper response.
|
|
14550
|
+
*/
|
|
14551
|
+
if (!handshakeResolver) {
|
|
14552
|
+
this.logger.trace(this.platformAuthType +
|
|
14553
|
+
`.onWindowMessage - resolver can't be found for request ${request.responseId}`);
|
|
14554
|
+
return;
|
|
14555
|
+
}
|
|
14556
|
+
// If we receive this message back it means no extension intercepted the request, meaning no extension supporting handshake protocol is installed
|
|
14557
|
+
this.logger.verbose(request.extensionId
|
|
14558
|
+
? `Extension with id: ${request.extensionId} not installed`
|
|
14559
|
+
: "No extension installed");
|
|
14560
|
+
clearTimeout(this.timeoutId);
|
|
14561
|
+
this.messageChannel.port1.close();
|
|
14562
|
+
this.messageChannel.port2.close();
|
|
14563
|
+
window.removeEventListener("message", this.windowListener, false);
|
|
14564
|
+
this.handshakeEvent.end({
|
|
14565
|
+
success: false,
|
|
14566
|
+
extensionInstalled: false,
|
|
14567
|
+
});
|
|
14568
|
+
handshakeResolver.reject(createBrowserAuthError(nativeExtensionNotInstalled));
|
|
14569
|
+
}
|
|
14570
|
+
}
|
|
14571
|
+
/**
|
|
14572
|
+
* Invoked when a message is received from the extension on the MessageChannel port
|
|
14573
|
+
* @param event
|
|
14574
|
+
*/
|
|
14575
|
+
onChannelMessage(event) {
|
|
14576
|
+
this.logger.trace(this.platformAuthType + " - onChannelMessage called.");
|
|
14577
|
+
const request = event.data;
|
|
14578
|
+
const resolver = this.resolvers.get(request.responseId);
|
|
14579
|
+
const handshakeResolver = this.handshakeResolvers.get(request.responseId);
|
|
14580
|
+
try {
|
|
14581
|
+
const method = request.body.method;
|
|
14582
|
+
if (method === NativeExtensionMethod.Response) {
|
|
14583
|
+
if (!resolver) {
|
|
14584
|
+
return;
|
|
14585
|
+
}
|
|
14586
|
+
const response = request.body.response;
|
|
14587
|
+
this.logger.trace(this.platformAuthType +
|
|
14588
|
+
" - Received response from browser extension");
|
|
14589
|
+
this.logger.tracePii(this.platformAuthType +
|
|
14590
|
+
` - Received response from browser extension: ${JSON.stringify(response)}`);
|
|
14591
|
+
if (response.status !== "Success") {
|
|
14592
|
+
resolver.reject(createNativeAuthError(response.code, response.description, response.ext));
|
|
14593
|
+
}
|
|
14594
|
+
else if (response.result) {
|
|
14595
|
+
if (response.result["code"] &&
|
|
14596
|
+
response.result["description"]) {
|
|
14597
|
+
resolver.reject(createNativeAuthError(response.result["code"], response.result["description"], response.result["ext"]));
|
|
14598
|
+
}
|
|
14599
|
+
else {
|
|
14600
|
+
resolver.resolve(response.result);
|
|
14601
|
+
}
|
|
14602
|
+
}
|
|
14603
|
+
else {
|
|
14604
|
+
throw createAuthError(unexpectedError, "Event does not contain result.");
|
|
14605
|
+
}
|
|
14606
|
+
this.resolvers.delete(request.responseId);
|
|
14607
|
+
}
|
|
14608
|
+
else if (method === NativeExtensionMethod.HandshakeResponse) {
|
|
14609
|
+
if (!handshakeResolver) {
|
|
14610
|
+
this.logger.trace(this.platformAuthType +
|
|
14611
|
+
`.onChannelMessage - resolver can't be found for request ${request.responseId}`);
|
|
14612
|
+
return;
|
|
14613
|
+
}
|
|
14614
|
+
clearTimeout(this.timeoutId); // Clear setTimeout
|
|
14615
|
+
window.removeEventListener("message", this.windowListener, false); // Remove 'No extension' listener
|
|
14616
|
+
this.extensionId = request.extensionId;
|
|
14617
|
+
this.extensionVersion = request.body.version;
|
|
14618
|
+
this.logger.verbose(this.platformAuthType +
|
|
14619
|
+
` - Received HandshakeResponse from extension: ${this.extensionId}`);
|
|
14620
|
+
this.handshakeEvent.end({
|
|
14621
|
+
extensionInstalled: true,
|
|
14622
|
+
success: true,
|
|
14623
|
+
});
|
|
14624
|
+
handshakeResolver.resolve();
|
|
14625
|
+
this.handshakeResolvers.delete(request.responseId);
|
|
14626
|
+
}
|
|
14627
|
+
// Do nothing if method is not Response or HandshakeResponse
|
|
14628
|
+
}
|
|
14629
|
+
catch (err) {
|
|
14630
|
+
this.logger.error("Error parsing response from WAM Extension");
|
|
14631
|
+
this.logger.errorPii(`Error parsing response from WAM Extension: ${err}`);
|
|
14632
|
+
this.logger.errorPii(`Unable to parse ${event}`);
|
|
14633
|
+
if (resolver) {
|
|
14634
|
+
resolver.reject(err);
|
|
14635
|
+
}
|
|
14636
|
+
else if (handshakeResolver) {
|
|
14637
|
+
handshakeResolver.reject(err);
|
|
14638
|
+
}
|
|
14223
14639
|
}
|
|
14224
|
-
this.performanceClient.addFields({
|
|
14225
|
-
extensionId: this.nativeMessageHandler.getExtensionId(),
|
|
14226
|
-
extensionVersion: this.nativeMessageHandler.getExtensionVersion(),
|
|
14227
|
-
matsBrokerVersion: mats.broker_version,
|
|
14228
|
-
matsAccountJoinOnStart: mats.account_join_on_start,
|
|
14229
|
-
matsAccountJoinOnEnd: mats.account_join_on_end,
|
|
14230
|
-
matsDeviceJoin: mats.device_join,
|
|
14231
|
-
matsPromptBehavior: mats.prompt_behavior,
|
|
14232
|
-
matsApiErrorCode: mats.api_error_code,
|
|
14233
|
-
matsUiVisible: mats.ui_visible,
|
|
14234
|
-
matsSilentCode: mats.silent_code,
|
|
14235
|
-
matsSilentBiSubCode: mats.silent_bi_sub_code,
|
|
14236
|
-
matsSilentMessage: mats.silent_message,
|
|
14237
|
-
matsSilentStatus: mats.silent_status,
|
|
14238
|
-
matsHttpStatus: mats.http_status,
|
|
14239
|
-
matsHttpEventCount: mats.http_event_count,
|
|
14240
|
-
}, this.correlationId);
|
|
14241
|
-
return mats;
|
|
14242
14640
|
}
|
|
14243
14641
|
/**
|
|
14244
14642
|
* Validates native platform response before processing
|
|
14245
14643
|
* @param response
|
|
14246
14644
|
*/
|
|
14247
|
-
|
|
14645
|
+
validatePlatformBrokerResponse(response) {
|
|
14248
14646
|
if (response.hasOwnProperty("access_token") &&
|
|
14249
14647
|
response.hasOwnProperty("id_token") &&
|
|
14250
14648
|
response.hasOwnProperty("client_info") &&
|
|
@@ -14258,425 +14656,258 @@ class NativeInteractionClient extends BaseInteractionClient {
|
|
|
14258
14656
|
}
|
|
14259
14657
|
}
|
|
14260
14658
|
/**
|
|
14261
|
-
*
|
|
14262
|
-
* @param response
|
|
14263
|
-
* @returns
|
|
14264
|
-
*/
|
|
14265
|
-
getMATSFromResponse(response) {
|
|
14266
|
-
if (response.properties.MATS) {
|
|
14267
|
-
try {
|
|
14268
|
-
return JSON.parse(response.properties.MATS);
|
|
14269
|
-
}
|
|
14270
|
-
catch (e) {
|
|
14271
|
-
this.logger.error("NativeInteractionClient - Error parsing MATS telemetry, returning null instead");
|
|
14272
|
-
}
|
|
14273
|
-
}
|
|
14274
|
-
return null;
|
|
14275
|
-
}
|
|
14276
|
-
/**
|
|
14277
|
-
* Returns whether or not response came from native cache
|
|
14278
|
-
* @param response
|
|
14659
|
+
* Returns the Id for the browser extension this handler is communicating with
|
|
14279
14660
|
* @returns
|
|
14280
14661
|
*/
|
|
14281
|
-
|
|
14282
|
-
|
|
14283
|
-
this.logger.verbose("NativeInteractionClient - MATS telemetry does not contain field indicating if response was served from cache. Returning false.");
|
|
14284
|
-
return false;
|
|
14285
|
-
}
|
|
14286
|
-
return !!mats.is_cached;
|
|
14287
|
-
}
|
|
14288
|
-
/**
|
|
14289
|
-
* Translates developer provided request object into NativeRequest object
|
|
14290
|
-
* @param request
|
|
14291
|
-
*/
|
|
14292
|
-
async initializeNativeRequest(request) {
|
|
14293
|
-
this.logger.trace("NativeInteractionClient - initializeNativeRequest called");
|
|
14294
|
-
const requestAuthority = request.authority || this.config.auth.authority;
|
|
14295
|
-
if (request.account) {
|
|
14296
|
-
// validate authority
|
|
14297
|
-
await this.getDiscoveredAuthority({
|
|
14298
|
-
requestAuthority,
|
|
14299
|
-
requestAzureCloudOptions: request.azureCloudOptions,
|
|
14300
|
-
account: request.account,
|
|
14301
|
-
});
|
|
14302
|
-
}
|
|
14303
|
-
const canonicalAuthority = new UrlString(requestAuthority);
|
|
14304
|
-
canonicalAuthority.validateAsUri();
|
|
14305
|
-
// scopes are expected to be received by the native broker as "scope" and will be added to the request below. Other properties that should be dropped from the request to the native broker can be included in the object destructuring here.
|
|
14306
|
-
const { scopes, ...remainingProperties } = request;
|
|
14307
|
-
const scopeSet = new ScopeSet(scopes || []);
|
|
14308
|
-
scopeSet.appendScopes(OIDC_DEFAULT_SCOPES);
|
|
14309
|
-
const getPrompt = () => {
|
|
14310
|
-
// If request is silent, prompt is always none
|
|
14311
|
-
switch (this.apiId) {
|
|
14312
|
-
case ApiId.ssoSilent:
|
|
14313
|
-
case ApiId.acquireTokenSilent_silentFlow:
|
|
14314
|
-
this.logger.trace("initializeNativeRequest: silent request sets prompt to none");
|
|
14315
|
-
return PromptValue.NONE;
|
|
14316
|
-
}
|
|
14317
|
-
// Prompt not provided, request may proceed and native broker decides if it needs to prompt
|
|
14318
|
-
if (!request.prompt) {
|
|
14319
|
-
this.logger.trace("initializeNativeRequest: prompt was not provided");
|
|
14320
|
-
return undefined;
|
|
14321
|
-
}
|
|
14322
|
-
// If request is interactive, check if prompt provided is allowed to go directly to native broker
|
|
14323
|
-
switch (request.prompt) {
|
|
14324
|
-
case PromptValue.NONE:
|
|
14325
|
-
case PromptValue.CONSENT:
|
|
14326
|
-
case PromptValue.LOGIN:
|
|
14327
|
-
this.logger.trace("initializeNativeRequest: prompt is compatible with native flow");
|
|
14328
|
-
return request.prompt;
|
|
14329
|
-
default:
|
|
14330
|
-
this.logger.trace(`initializeNativeRequest: prompt = ${request.prompt} is not compatible with native flow`);
|
|
14331
|
-
throw createBrowserAuthError(nativePromptNotSupported);
|
|
14332
|
-
}
|
|
14333
|
-
};
|
|
14334
|
-
const validatedRequest = {
|
|
14335
|
-
...remainingProperties,
|
|
14336
|
-
accountId: this.accountId,
|
|
14337
|
-
clientId: this.config.auth.clientId,
|
|
14338
|
-
authority: canonicalAuthority.urlString,
|
|
14339
|
-
scope: scopeSet.printScopes(),
|
|
14340
|
-
redirectUri: this.getRedirectUri(request.redirectUri),
|
|
14341
|
-
prompt: getPrompt(),
|
|
14342
|
-
correlationId: this.correlationId,
|
|
14343
|
-
tokenType: request.authenticationScheme,
|
|
14344
|
-
windowTitleSubstring: document.title,
|
|
14345
|
-
extraParameters: {
|
|
14346
|
-
...request.extraQueryParameters,
|
|
14347
|
-
...request.tokenQueryParameters,
|
|
14348
|
-
},
|
|
14349
|
-
extendedExpiryToken: false,
|
|
14350
|
-
keyId: request.popKid,
|
|
14351
|
-
};
|
|
14352
|
-
// Check for PoP token requests: signPopToken should only be set to true if popKid is not set
|
|
14353
|
-
if (validatedRequest.signPopToken && !!request.popKid) {
|
|
14354
|
-
throw createBrowserAuthError(invalidPopTokenRequest);
|
|
14355
|
-
}
|
|
14356
|
-
this.handleExtraBrokerParams(validatedRequest);
|
|
14357
|
-
validatedRequest.extraParameters =
|
|
14358
|
-
validatedRequest.extraParameters || {};
|
|
14359
|
-
validatedRequest.extraParameters.telemetry =
|
|
14360
|
-
NativeConstants.MATS_TELEMETRY;
|
|
14361
|
-
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14362
|
-
// add POP request type
|
|
14363
|
-
const shrParameters = {
|
|
14364
|
-
resourceRequestUri: request.resourceRequestUri,
|
|
14365
|
-
resourceRequestMethod: request.resourceRequestMethod,
|
|
14366
|
-
shrClaims: request.shrClaims,
|
|
14367
|
-
shrNonce: request.shrNonce,
|
|
14368
|
-
};
|
|
14369
|
-
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto);
|
|
14370
|
-
// generate reqCnf if not provided in the request
|
|
14371
|
-
let reqCnfData;
|
|
14372
|
-
if (!validatedRequest.keyId) {
|
|
14373
|
-
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(shrParameters, this.logger);
|
|
14374
|
-
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14375
|
-
validatedRequest.keyId = generatedReqCnfData.kid;
|
|
14376
|
-
validatedRequest.signPopToken = true;
|
|
14377
|
-
}
|
|
14378
|
-
else {
|
|
14379
|
-
reqCnfData = this.browserCrypto.base64UrlEncode(JSON.stringify({ kid: validatedRequest.keyId }));
|
|
14380
|
-
validatedRequest.signPopToken = false;
|
|
14381
|
-
}
|
|
14382
|
-
// SPAs require whole string to be passed to broker
|
|
14383
|
-
validatedRequest.reqCnf = reqCnfData;
|
|
14384
|
-
}
|
|
14385
|
-
this.addRequestSKUs(validatedRequest);
|
|
14386
|
-
return validatedRequest;
|
|
14387
|
-
}
|
|
14388
|
-
/**
|
|
14389
|
-
* Handles extra broker request parameters
|
|
14390
|
-
* @param request {NativeTokenRequest}
|
|
14391
|
-
* @private
|
|
14392
|
-
*/
|
|
14393
|
-
handleExtraBrokerParams(request) {
|
|
14394
|
-
const hasExtraBrokerParams = request.extraParameters &&
|
|
14395
|
-
request.extraParameters.hasOwnProperty(BROKER_CLIENT_ID) &&
|
|
14396
|
-
request.extraParameters.hasOwnProperty(BROKER_REDIRECT_URI) &&
|
|
14397
|
-
request.extraParameters.hasOwnProperty(CLIENT_ID);
|
|
14398
|
-
if (!request.embeddedClientId && !hasExtraBrokerParams) {
|
|
14399
|
-
return;
|
|
14400
|
-
}
|
|
14401
|
-
let child_client_id = "";
|
|
14402
|
-
const child_redirect_uri = request.redirectUri;
|
|
14403
|
-
if (request.embeddedClientId) {
|
|
14404
|
-
request.redirectUri = this.config.auth.redirectUri;
|
|
14405
|
-
child_client_id = request.embeddedClientId;
|
|
14406
|
-
}
|
|
14407
|
-
else if (request.extraParameters) {
|
|
14408
|
-
request.redirectUri =
|
|
14409
|
-
request.extraParameters[BROKER_REDIRECT_URI];
|
|
14410
|
-
child_client_id =
|
|
14411
|
-
request.extraParameters[CLIENT_ID];
|
|
14412
|
-
}
|
|
14413
|
-
request.extraParameters = {
|
|
14414
|
-
child_client_id,
|
|
14415
|
-
child_redirect_uri,
|
|
14416
|
-
};
|
|
14417
|
-
this.performanceClient?.addFields({
|
|
14418
|
-
embeddedClientId: child_client_id,
|
|
14419
|
-
embeddedRedirectUri: child_redirect_uri,
|
|
14420
|
-
}, request.correlationId);
|
|
14421
|
-
}
|
|
14422
|
-
}
|
|
14423
|
-
|
|
14424
|
-
/*
|
|
14425
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14426
|
-
* Licensed under the MIT License.
|
|
14427
|
-
*/
|
|
14428
|
-
/**
|
|
14429
|
-
* Returns map of parameters that are applicable to all calls to /authorize whether using PKCE or EAR
|
|
14430
|
-
* @param config
|
|
14431
|
-
* @param authority
|
|
14432
|
-
* @param request
|
|
14433
|
-
* @param logger
|
|
14434
|
-
* @param performanceClient
|
|
14435
|
-
* @returns
|
|
14436
|
-
*/
|
|
14437
|
-
async function getStandardParameters(config, authority, request, logger, performanceClient) {
|
|
14438
|
-
const parameters = getStandardAuthorizeRequestParameters({ ...config.auth, authority: authority }, request, logger, performanceClient);
|
|
14439
|
-
addLibraryInfo(parameters, {
|
|
14440
|
-
sku: BrowserConstants.MSAL_SKU,
|
|
14441
|
-
version: version,
|
|
14442
|
-
os: "",
|
|
14443
|
-
cpu: "",
|
|
14444
|
-
});
|
|
14445
|
-
if (config.auth.protocolMode !== ProtocolMode.OIDC) {
|
|
14446
|
-
addApplicationTelemetry(parameters, config.telemetry.application);
|
|
14447
|
-
}
|
|
14448
|
-
if (request.platformBroker) {
|
|
14449
|
-
// signal ests that this is a WAM call
|
|
14450
|
-
addNativeBroker(parameters);
|
|
14451
|
-
// pass the req_cnf for POP
|
|
14452
|
-
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14453
|
-
const cryptoOps = new CryptoOps(logger, performanceClient);
|
|
14454
|
-
const popTokenGenerator = new PopTokenGenerator(cryptoOps);
|
|
14455
|
-
// req_cnf is always sent as a string for SPAs
|
|
14456
|
-
let reqCnfData;
|
|
14457
|
-
if (!request.popKid) {
|
|
14458
|
-
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, logger, performanceClient, request.correlationId)(request, logger);
|
|
14459
|
-
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14460
|
-
}
|
|
14461
|
-
else {
|
|
14462
|
-
reqCnfData = cryptoOps.encodeKid(request.popKid);
|
|
14463
|
-
}
|
|
14464
|
-
addPopToken(parameters, reqCnfData);
|
|
14465
|
-
}
|
|
14662
|
+
getExtensionId() {
|
|
14663
|
+
return this.extensionId;
|
|
14466
14664
|
}
|
|
14467
|
-
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
|
|
14472
|
-
|
|
14473
|
-
* @param authority
|
|
14474
|
-
* @param request
|
|
14475
|
-
* @param logger
|
|
14476
|
-
* @param performanceClient
|
|
14477
|
-
* @returns
|
|
14478
|
-
*/
|
|
14479
|
-
async function getAuthCodeRequestUrl(config, authority, request, logger, performanceClient) {
|
|
14480
|
-
if (!request.codeChallenge) {
|
|
14481
|
-
throw createClientConfigurationError(pkceParamsMissing);
|
|
14665
|
+
/**
|
|
14666
|
+
* Returns the version for the browser extension this handler is communicating with
|
|
14667
|
+
* @returns
|
|
14668
|
+
*/
|
|
14669
|
+
getExtensionVersion() {
|
|
14670
|
+
return this.extensionVersion;
|
|
14482
14671
|
}
|
|
14483
|
-
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
|
|
14490
|
-
* Gets the form that will be posted to /authorize with request parameters when using EAR
|
|
14491
|
-
*/
|
|
14492
|
-
async function getEARForm(frame, config, authority, request, logger, performanceClient) {
|
|
14493
|
-
if (!request.earJwk) {
|
|
14494
|
-
throw createBrowserAuthError(earJwkEmpty);
|
|
14672
|
+
getExtensionName() {
|
|
14673
|
+
return this.getExtensionId() ===
|
|
14674
|
+
PlatformAuthConstants.PREFERRED_EXTENSION_ID
|
|
14675
|
+
? "chrome"
|
|
14676
|
+
: this.getExtensionId()?.length
|
|
14677
|
+
? "unknown"
|
|
14678
|
+
: undefined;
|
|
14495
14679
|
}
|
|
14496
|
-
|
|
14497
|
-
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
|
|
14501
|
-
const url = getAuthorizeUrl(authority, queryParams, config.auth.encodeExtraQueryParams, request.extraQueryParameters);
|
|
14502
|
-
return createForm(frame, url, parameters);
|
|
14503
|
-
}
|
|
14504
|
-
/**
|
|
14505
|
-
* Creates form element in the provided document with auth parameters in the post body
|
|
14506
|
-
* @param frame
|
|
14507
|
-
* @param authorizeUrl
|
|
14508
|
-
* @param parameters
|
|
14509
|
-
* @returns
|
|
14510
|
-
*/
|
|
14511
|
-
function createForm(frame, authorizeUrl, parameters) {
|
|
14512
|
-
const form = frame.createElement("form");
|
|
14513
|
-
form.method = "post";
|
|
14514
|
-
form.action = authorizeUrl;
|
|
14515
|
-
parameters.forEach((value, key) => {
|
|
14516
|
-
const param = frame.createElement("input");
|
|
14517
|
-
param.hidden = true;
|
|
14518
|
-
param.name = key;
|
|
14519
|
-
param.value = value;
|
|
14520
|
-
form.appendChild(param);
|
|
14521
|
-
});
|
|
14522
|
-
frame.body.appendChild(form);
|
|
14523
|
-
return form;
|
|
14524
|
-
}
|
|
14525
|
-
/**
|
|
14526
|
-
* Response handler when server returns accountId on the /authorize request
|
|
14527
|
-
* @param request
|
|
14528
|
-
* @param accountId
|
|
14529
|
-
* @param apiId
|
|
14530
|
-
* @param config
|
|
14531
|
-
* @param browserStorage
|
|
14532
|
-
* @param nativeStorage
|
|
14533
|
-
* @param eventHandler
|
|
14534
|
-
* @param logger
|
|
14535
|
-
* @param performanceClient
|
|
14536
|
-
* @param nativeMessageHandler
|
|
14537
|
-
* @returns
|
|
14680
|
+
}
|
|
14681
|
+
|
|
14682
|
+
/*
|
|
14683
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14684
|
+
* Licensed under the MIT License.
|
|
14538
14685
|
*/
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
14686
|
+
class PlatformAuthDOMHandler {
|
|
14687
|
+
constructor(logger, performanceClient, correlationId) {
|
|
14688
|
+
this.logger = logger;
|
|
14689
|
+
this.performanceClient = performanceClient;
|
|
14690
|
+
this.correlationId = correlationId;
|
|
14691
|
+
this.platformAuthType = PlatformAuthConstants.PLATFORM_DOM_PROVIDER;
|
|
14542
14692
|
}
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
* @param codeVerifier
|
|
14557
|
-
* @param authClient
|
|
14558
|
-
* @param browserStorage
|
|
14559
|
-
* @param logger
|
|
14560
|
-
* @param performanceClient
|
|
14561
|
-
* @returns
|
|
14562
|
-
*/
|
|
14563
|
-
async function handleResponseCode(request, response, codeVerifier, apiId, config, authClient, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler) {
|
|
14564
|
-
// Remove throttle if it exists
|
|
14565
|
-
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14566
|
-
if (response.accountId) {
|
|
14567
|
-
return invokeAsync(handleResponsePlatformBroker, PerformanceEvents.HandleResponsePlatformBroker, logger, performanceClient, request.correlationId)(request, response.accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler);
|
|
14693
|
+
static async createProvider(logger, performanceClient, correlationId) {
|
|
14694
|
+
logger.trace("PlatformAuthDOMHandler: createProvider called");
|
|
14695
|
+
// @ts-ignore
|
|
14696
|
+
if (window.navigator?.platformAuthentication) {
|
|
14697
|
+
const supportedContracts =
|
|
14698
|
+
// @ts-ignore
|
|
14699
|
+
await window.navigator.platformAuthentication.getSupportedContracts(PlatformAuthConstants.MICROSOFT_ENTRA_BROKERID);
|
|
14700
|
+
if (supportedContracts?.includes(PlatformAuthConstants.PLATFORM_DOM_APIS)) {
|
|
14701
|
+
logger.trace("Platform auth api available in DOM");
|
|
14702
|
+
return new PlatformAuthDOMHandler(logger, performanceClient, correlationId);
|
|
14703
|
+
}
|
|
14704
|
+
}
|
|
14705
|
+
return undefined;
|
|
14568
14706
|
}
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
|
|
14574
|
-
|
|
14575
|
-
const interactionHandler = new InteractionHandler(authClient, browserStorage, authCodeRequest, logger, performanceClient);
|
|
14576
|
-
// Handle response from hash string.
|
|
14577
|
-
const result = await invokeAsync(interactionHandler.handleCodeResponse.bind(interactionHandler), PerformanceEvents.HandleCodeResponse, logger, performanceClient, request.correlationId)(response, request);
|
|
14578
|
-
return result;
|
|
14579
|
-
}
|
|
14580
|
-
/**
|
|
14581
|
-
* Response handler when server returns ear_jwe on the /authorize request
|
|
14582
|
-
* @param request
|
|
14583
|
-
* @param response
|
|
14584
|
-
* @param apiId
|
|
14585
|
-
* @param config
|
|
14586
|
-
* @param authority
|
|
14587
|
-
* @param browserStorage
|
|
14588
|
-
* @param nativeStorage
|
|
14589
|
-
* @param eventHandler
|
|
14590
|
-
* @param logger
|
|
14591
|
-
* @param performanceClient
|
|
14592
|
-
* @param nativeMessageHandler
|
|
14593
|
-
* @returns
|
|
14594
|
-
*/
|
|
14595
|
-
async function handleResponseEAR(request, response, apiId, config, authority, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler) {
|
|
14596
|
-
// Remove throttle if it exists
|
|
14597
|
-
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14598
|
-
// Validate state & check response for errors
|
|
14599
|
-
validateAuthorizationResponse(response, request.state);
|
|
14600
|
-
if (!response.ear_jwe) {
|
|
14601
|
-
throw createBrowserAuthError(earJweEmpty);
|
|
14707
|
+
/**
|
|
14708
|
+
* Returns the Id for the broker extension this handler is communicating with
|
|
14709
|
+
* @returns
|
|
14710
|
+
*/
|
|
14711
|
+
getExtensionId() {
|
|
14712
|
+
return PlatformAuthConstants.MICROSOFT_ENTRA_BROKERID;
|
|
14602
14713
|
}
|
|
14603
|
-
|
|
14604
|
-
|
|
14714
|
+
getExtensionVersion() {
|
|
14715
|
+
return "";
|
|
14605
14716
|
}
|
|
14606
|
-
|
|
14607
|
-
|
|
14608
|
-
|
|
14717
|
+
getExtensionName() {
|
|
14718
|
+
return PlatformAuthConstants.DOM_API_NAME;
|
|
14719
|
+
}
|
|
14720
|
+
/**
|
|
14721
|
+
* Send token request to platform broker via browser DOM API
|
|
14722
|
+
* @param request
|
|
14723
|
+
* @returns
|
|
14724
|
+
*/
|
|
14725
|
+
async sendMessage(request) {
|
|
14726
|
+
this.logger.trace(this.platformAuthType + " - Sending request to browser DOM API");
|
|
14727
|
+
try {
|
|
14728
|
+
const platformDOMRequest = this.initializePlatformDOMRequest(request);
|
|
14729
|
+
const response =
|
|
14730
|
+
// @ts-ignore
|
|
14731
|
+
await window.navigator.platformAuthentication.executeGetToken(platformDOMRequest);
|
|
14732
|
+
return this.validatePlatformBrokerResponse(response);
|
|
14733
|
+
}
|
|
14734
|
+
catch (e) {
|
|
14735
|
+
this.logger.error(this.platformAuthType + " - executeGetToken DOM API error");
|
|
14736
|
+
throw e;
|
|
14737
|
+
}
|
|
14738
|
+
}
|
|
14739
|
+
initializePlatformDOMRequest(request) {
|
|
14740
|
+
this.logger.trace(this.platformAuthType + " - initializeNativeDOMRequest called");
|
|
14741
|
+
const { accountId, clientId, authority, scope, redirectUri, correlationId, state, storeInCache, embeddedClientId, extraParameters, ...remainingProperties } = request;
|
|
14742
|
+
const validExtraParameters = this.getDOMExtraParams(remainingProperties);
|
|
14743
|
+
const platformDOMRequest = {
|
|
14744
|
+
accountId: accountId,
|
|
14745
|
+
brokerId: this.getExtensionId(),
|
|
14746
|
+
authority: authority,
|
|
14747
|
+
clientId: clientId,
|
|
14748
|
+
correlationId: correlationId || this.correlationId,
|
|
14749
|
+
extraParameters: { ...extraParameters, ...validExtraParameters },
|
|
14750
|
+
isSecurityTokenService: false,
|
|
14751
|
+
redirectUri: redirectUri,
|
|
14752
|
+
scope: scope,
|
|
14753
|
+
state: state,
|
|
14754
|
+
storeInCache: storeInCache,
|
|
14755
|
+
embeddedClientId: embeddedClientId,
|
|
14756
|
+
};
|
|
14757
|
+
return platformDOMRequest;
|
|
14758
|
+
}
|
|
14759
|
+
validatePlatformBrokerResponse(response) {
|
|
14760
|
+
if (response.hasOwnProperty("isSuccess")) {
|
|
14761
|
+
if (response.hasOwnProperty("accessToken") &&
|
|
14762
|
+
response.hasOwnProperty("idToken") &&
|
|
14763
|
+
response.hasOwnProperty("clientInfo") &&
|
|
14764
|
+
response.hasOwnProperty("account") &&
|
|
14765
|
+
response.hasOwnProperty("scopes") &&
|
|
14766
|
+
response.hasOwnProperty("expiresIn")) {
|
|
14767
|
+
this.logger.trace(this.platformAuthType +
|
|
14768
|
+
" - platform broker returned successful and valid response");
|
|
14769
|
+
return this.convertToPlatformBrokerResponse(response);
|
|
14770
|
+
}
|
|
14771
|
+
else if (response.hasOwnProperty("error")) {
|
|
14772
|
+
const errorResponse = response;
|
|
14773
|
+
if (errorResponse.isSuccess === false &&
|
|
14774
|
+
errorResponse.error &&
|
|
14775
|
+
errorResponse.error.code) {
|
|
14776
|
+
this.logger.trace(this.platformAuthType +
|
|
14777
|
+
" - platform broker returned error response");
|
|
14778
|
+
throw createNativeAuthError(errorResponse.error.code, errorResponse.error.description, {
|
|
14779
|
+
error: parseInt(errorResponse.error.errorCode),
|
|
14780
|
+
protocol_error: errorResponse.error.protocolError,
|
|
14781
|
+
status: errorResponse.error.status,
|
|
14782
|
+
properties: errorResponse.error.properties,
|
|
14783
|
+
});
|
|
14784
|
+
}
|
|
14785
|
+
}
|
|
14786
|
+
}
|
|
14787
|
+
throw createAuthError(unexpectedError, "Response missing expected properties.");
|
|
14788
|
+
}
|
|
14789
|
+
convertToPlatformBrokerResponse(response) {
|
|
14790
|
+
this.logger.trace(this.platformAuthType + " - convertToNativeResponse called");
|
|
14791
|
+
const nativeResponse = {
|
|
14792
|
+
access_token: response.accessToken,
|
|
14793
|
+
id_token: response.idToken,
|
|
14794
|
+
client_info: response.clientInfo,
|
|
14795
|
+
account: response.account,
|
|
14796
|
+
expires_in: response.expiresIn,
|
|
14797
|
+
scope: response.scopes,
|
|
14798
|
+
state: response.state || "",
|
|
14799
|
+
properties: response.properties || {},
|
|
14800
|
+
extendedLifetimeToken: response.extendedLifetimeToken ?? false,
|
|
14801
|
+
shr: response.proofOfPossessionPayload,
|
|
14802
|
+
};
|
|
14803
|
+
return nativeResponse;
|
|
14804
|
+
}
|
|
14805
|
+
getDOMExtraParams(extraParameters) {
|
|
14806
|
+
const stringifiedParams = Object.entries(extraParameters).reduce((record, [key, value]) => {
|
|
14807
|
+
record[key] = String(value);
|
|
14808
|
+
return record;
|
|
14809
|
+
}, {});
|
|
14810
|
+
const validExtraParams = {
|
|
14811
|
+
...stringifiedParams,
|
|
14812
|
+
};
|
|
14813
|
+
return validExtraParams;
|
|
14609
14814
|
}
|
|
14610
|
-
const responseHandler = new ResponseHandler(config.auth.clientId, browserStorage, new CryptoOps(logger, performanceClient), logger, null, null, performanceClient);
|
|
14611
|
-
// Validate response. This function throws a server error if an error is returned by the server.
|
|
14612
|
-
responseHandler.validateTokenResponse(decryptedData);
|
|
14613
|
-
// Temporary until response handler is refactored to be more flow agnostic.
|
|
14614
|
-
const additionalData = {
|
|
14615
|
-
code: "",
|
|
14616
|
-
state: request.state,
|
|
14617
|
-
nonce: request.nonce,
|
|
14618
|
-
client_info: decryptedData.client_info,
|
|
14619
|
-
cloud_graph_host_name: decryptedData.cloud_graph_host_name,
|
|
14620
|
-
cloud_instance_host_name: decryptedData.cloud_instance_host_name,
|
|
14621
|
-
cloud_instance_name: decryptedData.cloud_instance_name,
|
|
14622
|
-
msgraph_host: decryptedData.msgraph_host,
|
|
14623
|
-
};
|
|
14624
|
-
return (await invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), PerformanceEvents.HandleServerTokenResponse, logger, performanceClient, request.correlationId)(decryptedData, authority, nowSeconds(), request, additionalData, undefined, undefined, undefined, undefined));
|
|
14625
14815
|
}
|
|
14626
14816
|
|
|
14627
14817
|
/*
|
|
14628
14818
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14629
14819
|
* Licensed under the MIT License.
|
|
14630
14820
|
*/
|
|
14631
|
-
// Constant byte array length
|
|
14632
|
-
const RANDOM_BYTE_ARR_LENGTH = 32;
|
|
14633
|
-
/**
|
|
14634
|
-
* This file defines APIs to generate PKCE codes and code verifiers.
|
|
14635
|
-
*/
|
|
14636
14821
|
/**
|
|
14637
|
-
*
|
|
14822
|
+
* Checks if the platform broker is available in the current environment.
|
|
14823
|
+
* @param loggerOptions
|
|
14824
|
+
* @param perfClient
|
|
14825
|
+
* @returns
|
|
14638
14826
|
*/
|
|
14639
|
-
async function
|
|
14640
|
-
|
|
14641
|
-
|
|
14642
|
-
const
|
|
14643
|
-
|
|
14644
|
-
|
|
14645
|
-
|
|
14646
|
-
}
|
|
14827
|
+
async function isPlatformBrokerAvailable(loggerOptions, perfClient, correlationId) {
|
|
14828
|
+
const logger = new Logger(loggerOptions || {}, name, version);
|
|
14829
|
+
logger.trace("isPlatformBrokerAvailable called");
|
|
14830
|
+
const performanceClient = perfClient || new StubPerformanceClient();
|
|
14831
|
+
if (typeof window === "undefined") {
|
|
14832
|
+
logger.trace("Non-browser environment detected, returning false");
|
|
14833
|
+
return false;
|
|
14834
|
+
}
|
|
14835
|
+
return !!(await getPlatformAuthProvider(logger, performanceClient, correlationId || createNewGuid()));
|
|
14647
14836
|
}
|
|
14648
|
-
|
|
14649
|
-
|
|
14650
|
-
|
|
14651
|
-
|
|
14652
|
-
|
|
14837
|
+
async function getPlatformAuthProvider(logger, performanceClient, correlationId, nativeBrokerHandshakeTimeout) {
|
|
14838
|
+
logger.trace("getPlatformAuthProvider called", correlationId);
|
|
14839
|
+
const enablePlatformBrokerDOMSupport = isDomEnabledForPlatformAuth();
|
|
14840
|
+
logger.trace("Has client allowed platform auth via DOM API: " +
|
|
14841
|
+
enablePlatformBrokerDOMSupport);
|
|
14842
|
+
let platformAuthProvider;
|
|
14653
14843
|
try {
|
|
14654
|
-
|
|
14655
|
-
|
|
14656
|
-
|
|
14657
|
-
|
|
14658
|
-
|
|
14659
|
-
|
|
14844
|
+
if (enablePlatformBrokerDOMSupport) {
|
|
14845
|
+
// Check if DOM platform API is supported first
|
|
14846
|
+
platformAuthProvider = await PlatformAuthDOMHandler.createProvider(logger, performanceClient, correlationId);
|
|
14847
|
+
}
|
|
14848
|
+
if (!platformAuthProvider) {
|
|
14849
|
+
logger.trace("Platform auth via DOM API not available, checking for extension");
|
|
14850
|
+
/*
|
|
14851
|
+
* If DOM APIs are not available, check if browser extension is available.
|
|
14852
|
+
* Platform authentication via DOM APIs is preferred over extension APIs.
|
|
14853
|
+
*/
|
|
14854
|
+
platformAuthProvider =
|
|
14855
|
+
await PlatformAuthExtensionHandler.createProvider(logger, nativeBrokerHandshakeTimeout ||
|
|
14856
|
+
DEFAULT_NATIVE_BROKER_HANDSHAKE_TIMEOUT_MS, performanceClient);
|
|
14857
|
+
}
|
|
14660
14858
|
}
|
|
14661
14859
|
catch (e) {
|
|
14662
|
-
|
|
14860
|
+
logger.trace("Platform auth not available", e);
|
|
14663
14861
|
}
|
|
14862
|
+
return platformAuthProvider;
|
|
14664
14863
|
}
|
|
14665
14864
|
/**
|
|
14666
|
-
*
|
|
14667
|
-
*
|
|
14865
|
+
* Returns true if the DOM API support for platform auth is enabled in session storage
|
|
14866
|
+
* @returns boolean
|
|
14867
|
+
* @deprecated
|
|
14668
14868
|
*/
|
|
14669
|
-
|
|
14670
|
-
|
|
14869
|
+
function isDomEnabledForPlatformAuth() {
|
|
14870
|
+
let sessionStorage;
|
|
14671
14871
|
try {
|
|
14672
|
-
|
|
14673
|
-
|
|
14674
|
-
|
|
14675
|
-
return urlEncodeArr(new Uint8Array(pkceHashedCodeVerifier));
|
|
14872
|
+
sessionStorage = window[BrowserCacheLocation.SessionStorage];
|
|
14873
|
+
// Mute errors if it's a non-browser environment or cookies are blocked.
|
|
14874
|
+
return sessionStorage?.getItem(PLATFORM_AUTH_DOM_SUPPORT) === "true";
|
|
14676
14875
|
}
|
|
14677
14876
|
catch (e) {
|
|
14678
|
-
|
|
14877
|
+
return false;
|
|
14878
|
+
}
|
|
14879
|
+
}
|
|
14880
|
+
/**
|
|
14881
|
+
* Returns boolean indicating whether or not the request should attempt to use native broker
|
|
14882
|
+
* @param logger
|
|
14883
|
+
* @param config
|
|
14884
|
+
* @param platformAuthProvider
|
|
14885
|
+
* @param authenticationScheme
|
|
14886
|
+
*/
|
|
14887
|
+
function isPlatformAuthAllowed(config, logger, platformAuthProvider, authenticationScheme) {
|
|
14888
|
+
logger.trace("isBrokerAvailable called");
|
|
14889
|
+
if (!config.system.allowPlatformBroker) {
|
|
14890
|
+
logger.trace("isBrokerAvailable: allowPlatformBroker is not enabled, returning false");
|
|
14891
|
+
// Developer disabled WAM
|
|
14892
|
+
return false;
|
|
14893
|
+
}
|
|
14894
|
+
if (!platformAuthProvider) {
|
|
14895
|
+
logger.trace("isBrokerAvailable: Platform auth provider is not initialized, returning false");
|
|
14896
|
+
// Platform broker auth providers are not available
|
|
14897
|
+
return false;
|
|
14898
|
+
}
|
|
14899
|
+
if (authenticationScheme) {
|
|
14900
|
+
switch (authenticationScheme) {
|
|
14901
|
+
case AuthenticationScheme.BEARER:
|
|
14902
|
+
case AuthenticationScheme.POP:
|
|
14903
|
+
logger.trace("isBrokerAvailable: authenticationScheme is supported, returning true");
|
|
14904
|
+
return true;
|
|
14905
|
+
default:
|
|
14906
|
+
logger.trace("isBrokerAvailable: authenticationScheme is not supported, returning false");
|
|
14907
|
+
return false;
|
|
14908
|
+
}
|
|
14679
14909
|
}
|
|
14910
|
+
return true;
|
|
14680
14911
|
}
|
|
14681
14912
|
|
|
14682
14913
|
/*
|
|
@@ -14684,8 +14915,8 @@ async function generateCodeChallengeFromVerifier(pkceCodeVerifier, performanceCl
|
|
|
14684
14915
|
* Licensed under the MIT License.
|
|
14685
14916
|
*/
|
|
14686
14917
|
class PopupClient extends StandardInteractionClient {
|
|
14687
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl,
|
|
14688
|
-
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
14918
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl, platformAuthHandler, correlationId) {
|
|
14919
|
+
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthHandler, correlationId);
|
|
14689
14920
|
// Properly sets this reference for the unload event.
|
|
14690
14921
|
this.unloadWindow = this.unloadWindow.bind(this);
|
|
14691
14922
|
this.nativeStorage = nativeStorageImpl;
|
|
@@ -14773,7 +15004,7 @@ class PopupClient extends StandardInteractionClient {
|
|
|
14773
15004
|
if (popupParams.popup) {
|
|
14774
15005
|
preconnect(validRequest.authority);
|
|
14775
15006
|
}
|
|
14776
|
-
const isPlatformBroker =
|
|
15007
|
+
const isPlatformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, request.authenticationScheme);
|
|
14777
15008
|
validRequest.platformBroker = isPlatformBroker;
|
|
14778
15009
|
if (this.config.auth.protocolMode === ProtocolMode.EAR) {
|
|
14779
15010
|
return this.executeEarFlow(validRequest, popupParams);
|
|
@@ -14815,7 +15046,7 @@ class PopupClient extends StandardInteractionClient {
|
|
|
14815
15046
|
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
|
|
14816
15047
|
const responseString = await this.monitorPopupForHash(popupWindow, popupParams.popupWindowParent);
|
|
14817
15048
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.serverResponseType, this.logger);
|
|
14818
|
-
return await invokeAsync(handleResponseCode, PerformanceEvents.HandleResponseCode, this.logger, this.performanceClient, correlationId)(request, serverParams, pkce.verifier, ApiId.acquireTokenPopup, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.
|
|
15049
|
+
return await invokeAsync(handleResponseCode, PerformanceEvents.HandleResponseCode, this.logger, this.performanceClient, correlationId)(request, serverParams, pkce.verifier, ApiId.acquireTokenPopup, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
|
|
14819
15050
|
}
|
|
14820
15051
|
catch (e) {
|
|
14821
15052
|
// Close the synchronous popup if an error is thrown before the window unload event is registered
|
|
@@ -14851,7 +15082,7 @@ class PopupClient extends StandardInteractionClient {
|
|
|
14851
15082
|
// Monitor the popup for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
|
|
14852
15083
|
const responseString = await invokeAsync(this.monitorPopupForHash.bind(this), PerformanceEvents.SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(popupWindow, popupParams.popupWindowParent);
|
|
14853
15084
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.serverResponseType, this.logger);
|
|
14854
|
-
return invokeAsync(handleResponseEAR, PerformanceEvents.HandleResponseEar, this.logger, this.performanceClient, correlationId)(popupRequest, serverParams, ApiId.acquireTokenPopup, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.
|
|
15085
|
+
return invokeAsync(handleResponseEAR, PerformanceEvents.HandleResponseEar, this.logger, this.performanceClient, correlationId)(popupRequest, serverParams, ApiId.acquireTokenPopup, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
|
|
14855
15086
|
}
|
|
14856
15087
|
/**
|
|
14857
15088
|
*
|
|
@@ -15148,8 +15379,8 @@ function getNavigationType() {
|
|
|
15148
15379
|
return navigation?.type;
|
|
15149
15380
|
}
|
|
15150
15381
|
class RedirectClient extends StandardInteractionClient {
|
|
15151
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl,
|
|
15152
|
-
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
15382
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl, platformAuthHandler, correlationId) {
|
|
15383
|
+
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthHandler, correlationId);
|
|
15153
15384
|
this.nativeStorage = nativeStorageImpl;
|
|
15154
15385
|
}
|
|
15155
15386
|
/**
|
|
@@ -15158,8 +15389,7 @@ class RedirectClient extends StandardInteractionClient {
|
|
|
15158
15389
|
*/
|
|
15159
15390
|
async acquireToken(request) {
|
|
15160
15391
|
const validRequest = await invokeAsync(this.initializeAuthorizationRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(request, exports.InteractionType.Redirect);
|
|
15161
|
-
validRequest.platformBroker =
|
|
15162
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeMessageHandler, request.authenticationScheme);
|
|
15392
|
+
validRequest.platformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, request.authenticationScheme);
|
|
15163
15393
|
const handleBackButton = (event) => {
|
|
15164
15394
|
// Clear temporary cache if the back button is clicked during the redirect flow.
|
|
15165
15395
|
if (event.persisted) {
|
|
@@ -15399,10 +15629,10 @@ class RedirectClient extends StandardInteractionClient {
|
|
|
15399
15629
|
requestExtraQueryParameters: request.extraQueryParameters,
|
|
15400
15630
|
account: request.account,
|
|
15401
15631
|
});
|
|
15402
|
-
return invokeAsync(handleResponseEAR, PerformanceEvents.HandleResponseEar, this.logger, this.performanceClient, request.correlationId)(request, serverParams, ApiId.acquireTokenRedirect, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.
|
|
15632
|
+
return invokeAsync(handleResponseEAR, PerformanceEvents.HandleResponseEar, this.logger, this.performanceClient, request.correlationId)(request, serverParams, ApiId.acquireTokenRedirect, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
|
|
15403
15633
|
}
|
|
15404
15634
|
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), PerformanceEvents.StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)({ serverTelemetryManager, requestAuthority: request.authority });
|
|
15405
|
-
return invokeAsync(handleResponseCode, PerformanceEvents.HandleResponseCode, this.logger, this.performanceClient, request.correlationId)(request, serverParams, codeVerifier, ApiId.acquireTokenRedirect, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.
|
|
15635
|
+
return invokeAsync(handleResponseCode, PerformanceEvents.HandleResponseCode, this.logger, this.performanceClient, request.correlationId)(request, serverParams, codeVerifier, ApiId.acquireTokenRedirect, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
|
|
15406
15636
|
}
|
|
15407
15637
|
/**
|
|
15408
15638
|
* Redirects window to given URL.
|
|
@@ -15686,8 +15916,8 @@ function removeHiddenIframe(iframe) {
|
|
|
15686
15916
|
* Licensed under the MIT License.
|
|
15687
15917
|
*/
|
|
15688
15918
|
class SilentIframeClient extends StandardInteractionClient {
|
|
15689
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, nativeStorageImpl,
|
|
15690
|
-
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
15919
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, nativeStorageImpl, platformAuthProvider, correlationId) {
|
|
15920
|
+
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthProvider, correlationId);
|
|
15691
15921
|
this.apiId = apiId;
|
|
15692
15922
|
this.nativeStorage = nativeStorageImpl;
|
|
15693
15923
|
}
|
|
@@ -15717,8 +15947,7 @@ class SilentIframeClient extends StandardInteractionClient {
|
|
|
15717
15947
|
}
|
|
15718
15948
|
// Create silent request
|
|
15719
15949
|
const silentRequest = await invokeAsync(this.initializeAuthorizationRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, request.correlationId)(inputRequest, exports.InteractionType.Silent);
|
|
15720
|
-
silentRequest.platformBroker =
|
|
15721
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeMessageHandler, silentRequest.authenticationScheme);
|
|
15950
|
+
silentRequest.platformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, silentRequest.authenticationScheme);
|
|
15722
15951
|
preconnect(silentRequest.authority);
|
|
15723
15952
|
if (this.config.auth.protocolMode === ProtocolMode.EAR) {
|
|
15724
15953
|
return this.executeEarFlow(silentRequest);
|
|
@@ -15784,7 +16013,7 @@ class SilentIframeClient extends StandardInteractionClient {
|
|
|
15784
16013
|
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
|
|
15785
16014
|
const responseString = await invokeAsync(monitorIframeForHash, PerformanceEvents.SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(msalFrame, this.config.system.iframeHashTimeout, this.config.system.pollIntervalMilliseconds, this.performanceClient, this.logger, correlationId, responseType);
|
|
15786
16015
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, correlationId)(responseString, responseType, this.logger);
|
|
15787
|
-
return invokeAsync(handleResponseEAR, PerformanceEvents.HandleResponseEar, this.logger, this.performanceClient, correlationId)(silentRequest, serverParams, this.apiId, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.
|
|
16016
|
+
return invokeAsync(handleResponseEAR, PerformanceEvents.HandleResponseEar, this.logger, this.performanceClient, correlationId)(silentRequest, serverParams, this.apiId, this.config, discoveredAuthority, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
|
|
15788
16017
|
}
|
|
15789
16018
|
/**
|
|
15790
16019
|
* Currently Unsupported
|
|
@@ -15815,7 +16044,7 @@ class SilentIframeClient extends StandardInteractionClient {
|
|
|
15815
16044
|
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
|
|
15816
16045
|
const responseString = await invokeAsync(monitorIframeForHash, PerformanceEvents.SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(msalFrame, this.config.system.iframeHashTimeout, this.config.system.pollIntervalMilliseconds, this.performanceClient, this.logger, correlationId, responseType);
|
|
15817
16046
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, correlationId)(responseString, responseType, this.logger);
|
|
15818
|
-
return invokeAsync(handleResponseCode, PerformanceEvents.HandleResponseCode, this.logger, this.performanceClient, correlationId)(request, serverParams, pkceCodes.verifier, this.apiId, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.
|
|
16047
|
+
return invokeAsync(handleResponseCode, PerformanceEvents.HandleResponseCode, this.logger, this.performanceClient, correlationId)(request, serverParams, pkceCodes.verifier, this.apiId, this.config, authClient, this.browserStorage, this.nativeStorage, this.eventHandler, this.logger, this.performanceClient, this.platformAuthProvider);
|
|
15819
16048
|
}
|
|
15820
16049
|
}
|
|
15821
16050
|
|
|
@@ -16096,8 +16325,8 @@ class HybridSpaAuthorizationCodeClient extends AuthorizationCodeClient {
|
|
|
16096
16325
|
* Licensed under the MIT License.
|
|
16097
16326
|
*/
|
|
16098
16327
|
class SilentAuthCodeClient extends StandardInteractionClient {
|
|
16099
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient,
|
|
16100
|
-
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
16328
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, platformAuthProvider, correlationId) {
|
|
16329
|
+
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthProvider, correlationId);
|
|
16101
16330
|
this.apiId = apiId;
|
|
16102
16331
|
}
|
|
16103
16332
|
/**
|
|
@@ -16155,6 +16384,25 @@ class SilentAuthCodeClient extends StandardInteractionClient {
|
|
|
16155
16384
|
}
|
|
16156
16385
|
}
|
|
16157
16386
|
|
|
16387
|
+
/*
|
|
16388
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
16389
|
+
* Licensed under the MIT License.
|
|
16390
|
+
*/
|
|
16391
|
+
function collectInstanceStats(currentClientId, performanceEvent, logger) {
|
|
16392
|
+
const frameInstances =
|
|
16393
|
+
// @ts-ignore
|
|
16394
|
+
window.msal?.clientIds || [];
|
|
16395
|
+
const msalInstanceCount = frameInstances.length;
|
|
16396
|
+
const sameClientIdInstanceCount = frameInstances.filter((i) => i === currentClientId).length;
|
|
16397
|
+
if (sameClientIdInstanceCount > 1) {
|
|
16398
|
+
logger.warning("There is already an instance of MSAL.js in the window with the same client id.");
|
|
16399
|
+
}
|
|
16400
|
+
performanceEvent.add({
|
|
16401
|
+
msalInstanceCount: msalInstanceCount,
|
|
16402
|
+
sameClientIdInstanceCount: sameClientIdInstanceCount,
|
|
16403
|
+
});
|
|
16404
|
+
}
|
|
16405
|
+
|
|
16158
16406
|
/*
|
|
16159
16407
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
16160
16408
|
* Licensed under the MIT License.
|
|
@@ -16266,7 +16514,7 @@ class StandardController {
|
|
|
16266
16514
|
* Initializer function to perform async startup tasks such as connecting to WAM extension
|
|
16267
16515
|
* @param request {?InitializeApplicationRequest} correlation id
|
|
16268
16516
|
*/
|
|
16269
|
-
async initialize(request) {
|
|
16517
|
+
async initialize(request, isBroker) {
|
|
16270
16518
|
this.logger.trace("initialize called");
|
|
16271
16519
|
if (this.initialized) {
|
|
16272
16520
|
this.logger.info("initialize has already been called, exiting early.");
|
|
@@ -16282,11 +16530,18 @@ class StandardController {
|
|
|
16282
16530
|
const allowPlatformBroker = this.config.system.allowPlatformBroker;
|
|
16283
16531
|
const initMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.InitializeClientApplication, initCorrelationId);
|
|
16284
16532
|
this.eventHandler.emitEvent(EventType.INITIALIZE_START);
|
|
16533
|
+
// Broker applications are initialized twice, so we avoid double-counting it
|
|
16534
|
+
if (!isBroker) {
|
|
16535
|
+
try {
|
|
16536
|
+
this.logMultipleInstances(initMeasurement);
|
|
16537
|
+
}
|
|
16538
|
+
catch { }
|
|
16539
|
+
}
|
|
16285
16540
|
await invokeAsync(this.browserStorage.initialize.bind(this.browserStorage), PerformanceEvents.InitializeCache, this.logger, this.performanceClient, initCorrelationId)(initCorrelationId);
|
|
16286
16541
|
if (allowPlatformBroker) {
|
|
16287
16542
|
try {
|
|
16288
|
-
|
|
16289
|
-
|
|
16543
|
+
// check if platform authentication is available via DOM or browser extension and create relevant handlers
|
|
16544
|
+
this.platformAuthProvider = await getPlatformAuthProvider(this.logger, this.performanceClient, initCorrelationId, this.config.system.nativeBrokerHandshakeTimeout);
|
|
16290
16545
|
}
|
|
16291
16546
|
catch (e) {
|
|
16292
16547
|
this.logger.verbose(e);
|
|
@@ -16356,18 +16611,15 @@ class StandardController {
|
|
|
16356
16611
|
}
|
|
16357
16612
|
const loggedInAccounts = this.getAllAccounts();
|
|
16358
16613
|
const platformBrokerRequest = this.browserStorage.getCachedNativeRequest();
|
|
16359
|
-
const useNative = platformBrokerRequest &&
|
|
16360
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeExtensionProvider) &&
|
|
16361
|
-
this.nativeExtensionProvider &&
|
|
16362
|
-
!hash;
|
|
16614
|
+
const useNative = platformBrokerRequest && this.platformAuthProvider && !hash;
|
|
16363
16615
|
let rootMeasurement;
|
|
16364
16616
|
this.eventHandler.emitEvent(EventType.HANDLE_REDIRECT_START, exports.InteractionType.Redirect);
|
|
16365
16617
|
let redirectResponse;
|
|
16366
16618
|
try {
|
|
16367
|
-
if (useNative && this.
|
|
16619
|
+
if (useNative && this.platformAuthProvider) {
|
|
16368
16620
|
rootMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenRedirect, platformBrokerRequest?.correlationId || "");
|
|
16369
16621
|
this.logger.trace("handleRedirectPromise - acquiring token from native platform");
|
|
16370
|
-
const nativeClient = new
|
|
16622
|
+
const nativeClient = new PlatformAuthInteractionClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.handleRedirectPromise, this.performanceClient, this.platformAuthProvider, platformBrokerRequest.accountId, this.nativeInternalStorage, platformBrokerRequest.correlationId);
|
|
16371
16623
|
redirectResponse = invokeAsync(nativeClient.handleRedirectPromise.bind(nativeClient), PerformanceEvents.HandleNativeRedirectPromiseMeasurement, this.logger, this.performanceClient, rootMeasurement.event.correlationId)(this.performanceClient, rootMeasurement.event.correlationId);
|
|
16372
16624
|
}
|
|
16373
16625
|
else {
|
|
@@ -16496,15 +16748,15 @@ class StandardController {
|
|
|
16496
16748
|
this.eventHandler.emitEvent(EventType.LOGIN_START, exports.InteractionType.Redirect, request);
|
|
16497
16749
|
}
|
|
16498
16750
|
let result;
|
|
16499
|
-
if (this.
|
|
16751
|
+
if (this.platformAuthProvider &&
|
|
16500
16752
|
this.canUsePlatformBroker(request)) {
|
|
16501
|
-
const nativeClient = new
|
|
16753
|
+
const nativeClient = new PlatformAuthInteractionClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenRedirect, this.performanceClient, this.platformAuthProvider, this.getNativeAccountId(request), this.nativeInternalStorage, correlationId);
|
|
16502
16754
|
result = nativeClient
|
|
16503
16755
|
.acquireTokenRedirect(request, atrMeasurement)
|
|
16504
16756
|
.catch((e) => {
|
|
16505
16757
|
if (e instanceof NativeAuthError &&
|
|
16506
16758
|
isFatalNativeAuthError(e)) {
|
|
16507
|
-
this.
|
|
16759
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16508
16760
|
const redirectClient = this.createRedirectClient(correlationId);
|
|
16509
16761
|
return redirectClient.acquireToken(request);
|
|
16510
16762
|
}
|
|
@@ -16585,7 +16837,7 @@ class StandardController {
|
|
|
16585
16837
|
.catch((e) => {
|
|
16586
16838
|
if (e instanceof NativeAuthError &&
|
|
16587
16839
|
isFatalNativeAuthError(e)) {
|
|
16588
|
-
this.
|
|
16840
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16589
16841
|
const popupClient = this.createPopupClient(correlationId);
|
|
16590
16842
|
return popupClient.acquireToken(request, pkce);
|
|
16591
16843
|
}
|
|
@@ -16694,7 +16946,7 @@ class StandardController {
|
|
|
16694
16946
|
result = this.acquireTokenNative(validRequest, ApiId.ssoSilent).catch((e) => {
|
|
16695
16947
|
// If native token acquisition fails for availability reasons fallback to standard flow
|
|
16696
16948
|
if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
|
|
16697
|
-
this.
|
|
16949
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16698
16950
|
const silentIframeClient = this.createSilentIframeClient(validRequest.correlationId);
|
|
16699
16951
|
return silentIframeClient.acquireToken(validRequest);
|
|
16700
16952
|
}
|
|
@@ -16796,7 +17048,7 @@ class StandardController {
|
|
|
16796
17048
|
// If native token acquisition fails for availability reasons fallback to standard flow
|
|
16797
17049
|
if (e instanceof NativeAuthError &&
|
|
16798
17050
|
isFatalNativeAuthError(e)) {
|
|
16799
|
-
this.
|
|
17051
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16800
17052
|
}
|
|
16801
17053
|
throw e;
|
|
16802
17054
|
});
|
|
@@ -17054,10 +17306,10 @@ class StandardController {
|
|
|
17054
17306
|
*/
|
|
17055
17307
|
async acquireTokenNative(request, apiId, accountId, cacheLookupPolicy) {
|
|
17056
17308
|
this.logger.trace("acquireTokenNative called");
|
|
17057
|
-
if (!this.
|
|
17309
|
+
if (!this.platformAuthProvider) {
|
|
17058
17310
|
throw createBrowserAuthError(nativeConnectionNotEstablished);
|
|
17059
17311
|
}
|
|
17060
|
-
const nativeClient = new
|
|
17312
|
+
const nativeClient = new PlatformAuthInteractionClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, apiId, this.performanceClient, this.platformAuthProvider, accountId || this.getNativeAccountId(request), this.nativeInternalStorage, request.correlationId);
|
|
17061
17313
|
return nativeClient.acquireToken(request, cacheLookupPolicy);
|
|
17062
17314
|
}
|
|
17063
17315
|
/**
|
|
@@ -17066,8 +17318,12 @@ class StandardController {
|
|
|
17066
17318
|
*/
|
|
17067
17319
|
canUsePlatformBroker(request, accountId) {
|
|
17068
17320
|
this.logger.trace("canUsePlatformBroker called");
|
|
17069
|
-
if (!
|
|
17070
|
-
this.logger.trace("canUsePlatformBroker:
|
|
17321
|
+
if (!this.platformAuthProvider) {
|
|
17322
|
+
this.logger.trace("canUsePlatformBroker: platform broker unavilable, returning false");
|
|
17323
|
+
return false;
|
|
17324
|
+
}
|
|
17325
|
+
if (!isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, request.authenticationScheme)) {
|
|
17326
|
+
this.logger.trace("canUsePlatformBroker: isBrokerAvailable returned false, returning false");
|
|
17071
17327
|
return false;
|
|
17072
17328
|
}
|
|
17073
17329
|
if (request.prompt) {
|
|
@@ -17107,39 +17363,39 @@ class StandardController {
|
|
|
17107
17363
|
* @param correlationId
|
|
17108
17364
|
*/
|
|
17109
17365
|
createPopupClient(correlationId) {
|
|
17110
|
-
return new PopupClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.
|
|
17366
|
+
return new PopupClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.platformAuthProvider, correlationId);
|
|
17111
17367
|
}
|
|
17112
17368
|
/**
|
|
17113
17369
|
* Returns new instance of the Redirect Interaction Client
|
|
17114
17370
|
* @param correlationId
|
|
17115
17371
|
*/
|
|
17116
17372
|
createRedirectClient(correlationId) {
|
|
17117
|
-
return new RedirectClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.
|
|
17373
|
+
return new RedirectClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.platformAuthProvider, correlationId);
|
|
17118
17374
|
}
|
|
17119
17375
|
/**
|
|
17120
17376
|
* Returns new instance of the Silent Iframe Interaction Client
|
|
17121
17377
|
* @param correlationId
|
|
17122
17378
|
*/
|
|
17123
17379
|
createSilentIframeClient(correlationId) {
|
|
17124
|
-
return new SilentIframeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.ssoSilent, this.performanceClient, this.nativeInternalStorage, this.
|
|
17380
|
+
return new SilentIframeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.ssoSilent, this.performanceClient, this.nativeInternalStorage, this.platformAuthProvider, correlationId);
|
|
17125
17381
|
}
|
|
17126
17382
|
/**
|
|
17127
17383
|
* Returns new instance of the Silent Cache Interaction Client
|
|
17128
17384
|
*/
|
|
17129
17385
|
createSilentCacheClient(correlationId) {
|
|
17130
|
-
return new SilentCacheClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.
|
|
17386
|
+
return new SilentCacheClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.platformAuthProvider, correlationId);
|
|
17131
17387
|
}
|
|
17132
17388
|
/**
|
|
17133
17389
|
* Returns new instance of the Silent Refresh Interaction Client
|
|
17134
17390
|
*/
|
|
17135
17391
|
createSilentRefreshClient(correlationId) {
|
|
17136
|
-
return new SilentRefreshClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.
|
|
17392
|
+
return new SilentRefreshClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.platformAuthProvider, correlationId);
|
|
17137
17393
|
}
|
|
17138
17394
|
/**
|
|
17139
17395
|
* Returns new instance of the Silent AuthCode Interaction Client
|
|
17140
17396
|
*/
|
|
17141
17397
|
createSilentAuthCodeClient(correlationId) {
|
|
17142
|
-
return new SilentAuthCodeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenByCode, this.performanceClient, this.
|
|
17398
|
+
return new SilentAuthCodeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenByCode, this.performanceClient, this.platformAuthProvider, correlationId);
|
|
17143
17399
|
}
|
|
17144
17400
|
/**
|
|
17145
17401
|
* Adds event callbacks to array
|
|
@@ -17485,14 +17741,14 @@ class StandardController {
|
|
|
17485
17741
|
*/
|
|
17486
17742
|
async acquireTokenSilentNoIframe(silentRequest, cacheLookupPolicy) {
|
|
17487
17743
|
// if the cache policy is set to access_token only, we should not be hitting the native layer yet
|
|
17488
|
-
if (
|
|
17744
|
+
if (isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, silentRequest.authenticationScheme) &&
|
|
17489
17745
|
silentRequest.account.nativeAccountId) {
|
|
17490
17746
|
this.logger.verbose("acquireTokenSilent - attempting to acquire token from native platform");
|
|
17491
17747
|
return this.acquireTokenNative(silentRequest, ApiId.acquireTokenSilent_silentFlow, silentRequest.account.nativeAccountId, cacheLookupPolicy).catch(async (e) => {
|
|
17492
17748
|
// If native token acquisition fails for availability reasons fallback to web flow
|
|
17493
17749
|
if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
|
|
17494
17750
|
this.logger.verbose("acquireTokenSilent - native platform unavailable, falling back to web flow");
|
|
17495
|
-
this.
|
|
17751
|
+
this.platformAuthProvider = undefined; // Prevent future requests from continuing to attempt
|
|
17496
17752
|
// Cache will not contain tokens, given that previous WAM requests succeeded. Skip cache and RT renewal and go straight to iframe renewal
|
|
17497
17753
|
throw createClientAuthError(tokenRefreshRequired);
|
|
17498
17754
|
}
|
|
@@ -17535,6 +17791,23 @@ class StandardController {
|
|
|
17535
17791
|
this.performanceClient.addFields({ usePreGeneratedPkce: !!res }, correlationId);
|
|
17536
17792
|
return res;
|
|
17537
17793
|
}
|
|
17794
|
+
logMultipleInstances(performanceEvent) {
|
|
17795
|
+
const clientId = this.config.auth.clientId;
|
|
17796
|
+
if (!window)
|
|
17797
|
+
return;
|
|
17798
|
+
// @ts-ignore
|
|
17799
|
+
window.msal = window.msal || {};
|
|
17800
|
+
// @ts-ignore
|
|
17801
|
+
window.msal.clientIds = window.msal.clientIds || [];
|
|
17802
|
+
// @ts-ignore
|
|
17803
|
+
const clientIds = window.msal.clientIds;
|
|
17804
|
+
if (clientIds.length > 0) {
|
|
17805
|
+
this.logger.verbose("There is already an instance of MSAL.js in the window.");
|
|
17806
|
+
}
|
|
17807
|
+
// @ts-ignore
|
|
17808
|
+
window.msal.clientIds.push(clientId);
|
|
17809
|
+
collectInstanceStats(clientId, performanceEvent, this.logger);
|
|
17810
|
+
}
|
|
17538
17811
|
}
|
|
17539
17812
|
/**
|
|
17540
17813
|
* Determines whether an error thrown by the refresh token endpoint can be resolved without interaction
|
|
@@ -17821,7 +18094,9 @@ class NestedAppAuthController {
|
|
|
17821
18094
|
* Specific implementation of initialize function for NestedAppAuthController
|
|
17822
18095
|
* @returns
|
|
17823
18096
|
*/
|
|
17824
|
-
async initialize(request
|
|
18097
|
+
async initialize(request,
|
|
18098
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
18099
|
+
isBroker) {
|
|
17825
18100
|
const initCorrelationId = request?.correlationId || createNewGuid();
|
|
17826
18101
|
await this.browserStorage.initialize(initCorrelationId);
|
|
17827
18102
|
return Promise.resolve();
|
|
@@ -18343,6 +18618,7 @@ class PublicClientApplication {
|
|
|
18343
18618
|
* @param IController Optional parameter to explictly set the controller. (Will be removed when we remove public constructor)
|
|
18344
18619
|
*/
|
|
18345
18620
|
constructor(configuration, controller) {
|
|
18621
|
+
this.isBroker = false;
|
|
18346
18622
|
this.controller =
|
|
18347
18623
|
controller ||
|
|
18348
18624
|
new StandardController(new StandardOperatingContext(configuration));
|
|
@@ -18352,7 +18628,7 @@ class PublicClientApplication {
|
|
|
18352
18628
|
* @param request {?InitializeApplicationRequest}
|
|
18353
18629
|
*/
|
|
18354
18630
|
async initialize(request) {
|
|
18355
|
-
return this.controller.initialize(request);
|
|
18631
|
+
return this.controller.initialize(request, this.isBroker);
|
|
18356
18632
|
}
|
|
18357
18633
|
/**
|
|
18358
18634
|
* Use when you want to obtain an access_token for your API via opening a popup window in the user's browser
|
|
@@ -19855,6 +20131,7 @@ exports.UrlString = UrlString;
|
|
|
19855
20131
|
exports.WrapperSKU = WrapperSKU;
|
|
19856
20132
|
exports.createNestablePublicClientApplication = createNestablePublicClientApplication;
|
|
19857
20133
|
exports.createStandardPublicClientApplication = createStandardPublicClientApplication;
|
|
20134
|
+
exports.isPlatformBrokerAvailable = isPlatformBrokerAvailable;
|
|
19858
20135
|
exports.stubbedPublicClientApplication = stubbedPublicClientApplication;
|
|
19859
20136
|
exports.version = version;
|
|
19860
20137
|
//# sourceMappingURL=msal-browser.cjs.map
|