@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.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @azure/msal-browser v4.
|
|
1
|
+
/*! @azure/msal-browser v4.13.0 2025-05-30 */
|
|
2
2
|
'use strict';
|
|
3
3
|
(function (global, factory) {
|
|
4
4
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.msal = {}));
|
|
7
7
|
})(this, (function (exports) { 'use strict';
|
|
8
8
|
|
|
9
|
-
/*! @azure/msal-common v15.
|
|
9
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
10
10
|
/*
|
|
11
11
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
12
12
|
* Licensed under the MIT License.
|
|
@@ -260,13 +260,6 @@
|
|
|
260
260
|
INVALID_GRANT_ERROR: "invalid_grant",
|
|
261
261
|
CLIENT_MISMATCH_ERROR: "client_mismatch",
|
|
262
262
|
};
|
|
263
|
-
/**
|
|
264
|
-
* Response codes
|
|
265
|
-
*/
|
|
266
|
-
const ResponseCodes = {
|
|
267
|
-
httpSuccess: 200,
|
|
268
|
-
httpBadRequest: 400,
|
|
269
|
-
};
|
|
270
263
|
/**
|
|
271
264
|
* Region Discovery Sources
|
|
272
265
|
*/
|
|
@@ -309,7 +302,7 @@
|
|
|
309
302
|
// Token renewal offset default in seconds
|
|
310
303
|
const DEFAULT_TOKEN_RENEWAL_OFFSET_SEC = 300;
|
|
311
304
|
|
|
312
|
-
/*! @azure/msal-common v15.
|
|
305
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
313
306
|
/*
|
|
314
307
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
315
308
|
* Licensed under the MIT License.
|
|
@@ -326,7 +319,7 @@
|
|
|
326
319
|
unexpectedError: unexpectedError
|
|
327
320
|
});
|
|
328
321
|
|
|
329
|
-
/*! @azure/msal-common v15.
|
|
322
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
330
323
|
|
|
331
324
|
/*
|
|
332
325
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -375,7 +368,7 @@
|
|
|
375
368
|
: AuthErrorMessages[code]);
|
|
376
369
|
}
|
|
377
370
|
|
|
378
|
-
/*! @azure/msal-common v15.
|
|
371
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
379
372
|
/*
|
|
380
373
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
381
374
|
* Licensed under the MIT License.
|
|
@@ -473,7 +466,7 @@
|
|
|
473
466
|
userTimeoutReached: userTimeoutReached
|
|
474
467
|
});
|
|
475
468
|
|
|
476
|
-
/*! @azure/msal-common v15.
|
|
469
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
477
470
|
|
|
478
471
|
/*
|
|
479
472
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -725,7 +718,7 @@
|
|
|
725
718
|
return new ClientAuthError(errorCode, additionalMessage);
|
|
726
719
|
}
|
|
727
720
|
|
|
728
|
-
/*! @azure/msal-common v15.
|
|
721
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
729
722
|
|
|
730
723
|
/*
|
|
731
724
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -764,7 +757,7 @@
|
|
|
764
757
|
},
|
|
765
758
|
};
|
|
766
759
|
|
|
767
|
-
/*! @azure/msal-common v15.
|
|
760
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
768
761
|
|
|
769
762
|
/*
|
|
770
763
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -955,12 +948,12 @@
|
|
|
955
948
|
}
|
|
956
949
|
}
|
|
957
950
|
|
|
958
|
-
/*! @azure/msal-common v15.
|
|
951
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
959
952
|
/* eslint-disable header/header */
|
|
960
953
|
const name$1 = "@azure/msal-common";
|
|
961
|
-
const version$1 = "15.
|
|
954
|
+
const version$1 = "15.7.0";
|
|
962
955
|
|
|
963
|
-
/*! @azure/msal-common v15.
|
|
956
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
964
957
|
/*
|
|
965
958
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
966
959
|
* Licensed under the MIT License.
|
|
@@ -980,7 +973,7 @@
|
|
|
980
973
|
AzureUsGovernment: "https://login.microsoftonline.us",
|
|
981
974
|
};
|
|
982
975
|
|
|
983
|
-
/*! @azure/msal-common v15.
|
|
976
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
984
977
|
|
|
985
978
|
/*
|
|
986
979
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1041,7 +1034,7 @@
|
|
|
1041
1034
|
}
|
|
1042
1035
|
}
|
|
1043
1036
|
|
|
1044
|
-
/*! @azure/msal-common v15.
|
|
1037
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1045
1038
|
/*
|
|
1046
1039
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1047
1040
|
* Licensed under the MIT License.
|
|
@@ -1096,7 +1089,7 @@
|
|
|
1096
1089
|
return cachedAtSec > nowSeconds();
|
|
1097
1090
|
}
|
|
1098
1091
|
|
|
1099
|
-
/*! @azure/msal-common v15.
|
|
1092
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1100
1093
|
|
|
1101
1094
|
/*
|
|
1102
1095
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1423,7 +1416,7 @@
|
|
|
1423
1416
|
return metadata.expiresAt <= nowSeconds();
|
|
1424
1417
|
}
|
|
1425
1418
|
|
|
1426
|
-
/*! @azure/msal-common v15.
|
|
1419
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1427
1420
|
/*
|
|
1428
1421
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1429
1422
|
* Licensed under the MIT License.
|
|
@@ -1477,7 +1470,7 @@
|
|
|
1477
1470
|
urlParseError: urlParseError
|
|
1478
1471
|
});
|
|
1479
1472
|
|
|
1480
|
-
/*! @azure/msal-common v15.
|
|
1473
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1481
1474
|
|
|
1482
1475
|
/*
|
|
1483
1476
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1615,7 +1608,7 @@
|
|
|
1615
1608
|
return new ClientConfigurationError(errorCode);
|
|
1616
1609
|
}
|
|
1617
1610
|
|
|
1618
|
-
/*! @azure/msal-common v15.
|
|
1611
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1619
1612
|
/*
|
|
1620
1613
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1621
1614
|
* Licensed under the MIT License.
|
|
@@ -1712,7 +1705,7 @@
|
|
|
1712
1705
|
}
|
|
1713
1706
|
}
|
|
1714
1707
|
|
|
1715
|
-
/*! @azure/msal-common v15.
|
|
1708
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1716
1709
|
|
|
1717
1710
|
/*
|
|
1718
1711
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1903,7 +1896,7 @@
|
|
|
1903
1896
|
}
|
|
1904
1897
|
}
|
|
1905
1898
|
|
|
1906
|
-
/*! @azure/msal-common v15.
|
|
1899
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1907
1900
|
|
|
1908
1901
|
/*
|
|
1909
1902
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -1943,7 +1936,7 @@
|
|
|
1943
1936
|
};
|
|
1944
1937
|
}
|
|
1945
1938
|
|
|
1946
|
-
/*! @azure/msal-common v15.
|
|
1939
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
1947
1940
|
/*
|
|
1948
1941
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1949
1942
|
* Licensed under the MIT License.
|
|
@@ -2022,7 +2015,7 @@
|
|
|
2022
2015
|
return updatedAccountInfo;
|
|
2023
2016
|
}
|
|
2024
2017
|
|
|
2025
|
-
/*! @azure/msal-common v15.
|
|
2018
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2026
2019
|
/*
|
|
2027
2020
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2028
2021
|
* Licensed under the MIT License.
|
|
@@ -2037,7 +2030,7 @@
|
|
|
2037
2030
|
Ciam: 3,
|
|
2038
2031
|
};
|
|
2039
2032
|
|
|
2040
|
-
/*! @azure/msal-common v15.
|
|
2033
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2041
2034
|
/*
|
|
2042
2035
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2043
2036
|
* Licensed under the MIT License.
|
|
@@ -2059,7 +2052,7 @@
|
|
|
2059
2052
|
return null;
|
|
2060
2053
|
}
|
|
2061
2054
|
|
|
2062
|
-
/*! @azure/msal-common v15.
|
|
2055
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2063
2056
|
/*
|
|
2064
2057
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2065
2058
|
* Licensed under the MIT License.
|
|
@@ -2083,7 +2076,7 @@
|
|
|
2083
2076
|
EAR: "EAR",
|
|
2084
2077
|
};
|
|
2085
2078
|
|
|
2086
|
-
/*! @azure/msal-common v15.
|
|
2079
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2087
2080
|
|
|
2088
2081
|
/*
|
|
2089
2082
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2326,7 +2319,7 @@
|
|
|
2326
2319
|
}
|
|
2327
2320
|
}
|
|
2328
2321
|
|
|
2329
|
-
/*! @azure/msal-common v15.
|
|
2322
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2330
2323
|
|
|
2331
2324
|
/*
|
|
2332
2325
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2391,7 +2384,7 @@
|
|
|
2391
2384
|
return queryParameterArray.join("&");
|
|
2392
2385
|
}
|
|
2393
2386
|
|
|
2394
|
-
/*! @azure/msal-common v15.
|
|
2387
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2395
2388
|
|
|
2396
2389
|
/*
|
|
2397
2390
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2555,7 +2548,7 @@
|
|
|
2555
2548
|
}
|
|
2556
2549
|
}
|
|
2557
2550
|
|
|
2558
|
-
/*! @azure/msal-common v15.
|
|
2551
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2559
2552
|
|
|
2560
2553
|
/*
|
|
2561
2554
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2695,7 +2688,7 @@
|
|
|
2695
2688
|
return null;
|
|
2696
2689
|
}
|
|
2697
2690
|
|
|
2698
|
-
/*! @azure/msal-common v15.
|
|
2691
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2699
2692
|
/*
|
|
2700
2693
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2701
2694
|
* Licensed under the MIT License.
|
|
@@ -2703,7 +2696,7 @@
|
|
|
2703
2696
|
const cacheQuotaExceededErrorCode = "cache_quota_exceeded";
|
|
2704
2697
|
const cacheUnknownErrorCode = "cache_error_unknown";
|
|
2705
2698
|
|
|
2706
|
-
/*! @azure/msal-common v15.
|
|
2699
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2707
2700
|
|
|
2708
2701
|
/*
|
|
2709
2702
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -2730,7 +2723,7 @@
|
|
|
2730
2723
|
}
|
|
2731
2724
|
}
|
|
2732
2725
|
|
|
2733
|
-
/*! @azure/msal-common v15.
|
|
2726
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
2734
2727
|
|
|
2735
2728
|
/*
|
|
2736
2729
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -3915,7 +3908,7 @@
|
|
|
3915
3908
|
}
|
|
3916
3909
|
}
|
|
3917
3910
|
|
|
3918
|
-
/*! @azure/msal-common v15.
|
|
3911
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
3919
3912
|
|
|
3920
3913
|
/*
|
|
3921
3914
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -4015,7 +4008,7 @@
|
|
|
4015
4008
|
return (config.authOptions.authority.options.protocolMode === ProtocolMode.OIDC);
|
|
4016
4009
|
}
|
|
4017
4010
|
|
|
4018
|
-
/*! @azure/msal-common v15.
|
|
4011
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4019
4012
|
/*
|
|
4020
4013
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4021
4014
|
* Licensed under the MIT License.
|
|
@@ -4025,7 +4018,7 @@
|
|
|
4025
4018
|
UPN: "UPN",
|
|
4026
4019
|
};
|
|
4027
4020
|
|
|
4028
|
-
/*! @azure/msal-common v15.
|
|
4021
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4029
4022
|
/*
|
|
4030
4023
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4031
4024
|
* Licensed under the MIT License.
|
|
@@ -4075,7 +4068,7 @@
|
|
|
4075
4068
|
const EAR_JWK = "ear_jwk";
|
|
4076
4069
|
const EAR_JWE_CRYPTO = "ear_jwe_crypto";
|
|
4077
4070
|
|
|
4078
|
-
/*! @azure/msal-common v15.
|
|
4071
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4079
4072
|
|
|
4080
4073
|
/*
|
|
4081
4074
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -4443,7 +4436,7 @@
|
|
|
4443
4436
|
parameters.set(EAR_JWE_CRYPTO, jweCryptoB64Encoded);
|
|
4444
4437
|
}
|
|
4445
4438
|
|
|
4446
|
-
/*! @azure/msal-common v15.
|
|
4439
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4447
4440
|
/*
|
|
4448
4441
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4449
4442
|
* Licensed under the MIT License.
|
|
@@ -4455,7 +4448,7 @@
|
|
|
4455
4448
|
response.hasOwnProperty("jwks_uri"));
|
|
4456
4449
|
}
|
|
4457
4450
|
|
|
4458
|
-
/*! @azure/msal-common v15.
|
|
4451
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4459
4452
|
/*
|
|
4460
4453
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4461
4454
|
* Licensed under the MIT License.
|
|
@@ -4465,7 +4458,7 @@
|
|
|
4465
4458
|
response.hasOwnProperty("metadata"));
|
|
4466
4459
|
}
|
|
4467
4460
|
|
|
4468
|
-
/*! @azure/msal-common v15.
|
|
4461
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4469
4462
|
/*
|
|
4470
4463
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4471
4464
|
* Licensed under the MIT License.
|
|
@@ -4475,7 +4468,7 @@
|
|
|
4475
4468
|
response.hasOwnProperty("error_description"));
|
|
4476
4469
|
}
|
|
4477
4470
|
|
|
4478
|
-
/*! @azure/msal-common v15.
|
|
4471
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4479
4472
|
/*
|
|
4480
4473
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4481
4474
|
* Licensed under the MIT License.
|
|
@@ -4988,7 +4981,7 @@
|
|
|
4988
4981
|
"encryptedCacheExpiredCount",
|
|
4989
4982
|
]);
|
|
4990
4983
|
|
|
4991
|
-
/*! @azure/msal-common v15.
|
|
4984
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
4992
4985
|
/*
|
|
4993
4986
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4994
4987
|
* Licensed under the MIT License.
|
|
@@ -5084,7 +5077,7 @@
|
|
|
5084
5077
|
};
|
|
5085
5078
|
};
|
|
5086
5079
|
|
|
5087
|
-
/*! @azure/msal-common v15.
|
|
5080
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
5088
5081
|
|
|
5089
5082
|
/*
|
|
5090
5083
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -5111,15 +5104,13 @@
|
|
|
5111
5104
|
const options = RegionDiscovery.IMDS_OPTIONS;
|
|
5112
5105
|
try {
|
|
5113
5106
|
const localIMDSVersionResponse = await invokeAsync(this.getRegionFromIMDS.bind(this), PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.logger, this.performanceClient, this.correlationId)(Constants.IMDS_VERSION, options);
|
|
5114
|
-
if (localIMDSVersionResponse.status ===
|
|
5115
|
-
ResponseCodes.httpSuccess) {
|
|
5107
|
+
if (localIMDSVersionResponse.status === HttpStatus.SUCCESS) {
|
|
5116
5108
|
autodetectedRegionName = localIMDSVersionResponse.body;
|
|
5117
5109
|
regionDiscoveryMetadata.region_source =
|
|
5118
5110
|
RegionDiscoverySources.IMDS;
|
|
5119
5111
|
}
|
|
5120
5112
|
// If the response using the local IMDS version failed, try to fetch the current version of IMDS and retry.
|
|
5121
|
-
if (localIMDSVersionResponse.status ===
|
|
5122
|
-
ResponseCodes.httpBadRequest) {
|
|
5113
|
+
if (localIMDSVersionResponse.status === HttpStatus.BAD_REQUEST) {
|
|
5123
5114
|
const currentIMDSVersion = await invokeAsync(this.getCurrentVersion.bind(this), PerformanceEvents.RegionDiscoveryGetCurrentVersion, this.logger, this.performanceClient, this.correlationId)(options);
|
|
5124
5115
|
if (!currentIMDSVersion) {
|
|
5125
5116
|
regionDiscoveryMetadata.region_source =
|
|
@@ -5127,8 +5118,7 @@
|
|
|
5127
5118
|
return null;
|
|
5128
5119
|
}
|
|
5129
5120
|
const currentIMDSVersionResponse = await invokeAsync(this.getRegionFromIMDS.bind(this), PerformanceEvents.RegionDiscoveryGetRegionFromIMDS, this.logger, this.performanceClient, this.correlationId)(currentIMDSVersion, options);
|
|
5130
|
-
if (currentIMDSVersionResponse.status ===
|
|
5131
|
-
ResponseCodes.httpSuccess) {
|
|
5121
|
+
if (currentIMDSVersionResponse.status === HttpStatus.SUCCESS) {
|
|
5132
5122
|
autodetectedRegionName =
|
|
5133
5123
|
currentIMDSVersionResponse.body;
|
|
5134
5124
|
regionDiscoveryMetadata.region_source =
|
|
@@ -5173,7 +5163,7 @@
|
|
|
5173
5163
|
try {
|
|
5174
5164
|
const response = await this.networkInterface.sendGetRequestAsync(`${Constants.IMDS_ENDPOINT}?format=json`, options);
|
|
5175
5165
|
// When IMDS endpoint is called without the api version query param, bad request response comes back with latest version.
|
|
5176
|
-
if (response.status ===
|
|
5166
|
+
if (response.status === HttpStatus.BAD_REQUEST &&
|
|
5177
5167
|
response.body &&
|
|
5178
5168
|
response.body["newest-versions"] &&
|
|
5179
5169
|
response.body["newest-versions"].length > 0) {
|
|
@@ -5193,7 +5183,7 @@
|
|
|
5193
5183
|
},
|
|
5194
5184
|
};
|
|
5195
5185
|
|
|
5196
|
-
/*! @azure/msal-common v15.
|
|
5186
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
5197
5187
|
|
|
5198
5188
|
/*
|
|
5199
5189
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6032,7 +6022,7 @@
|
|
|
6032
6022
|
};
|
|
6033
6023
|
}
|
|
6034
6024
|
|
|
6035
|
-
/*! @azure/msal-common v15.
|
|
6025
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6036
6026
|
|
|
6037
6027
|
/*
|
|
6038
6028
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6063,7 +6053,7 @@
|
|
|
6063
6053
|
}
|
|
6064
6054
|
}
|
|
6065
6055
|
|
|
6066
|
-
/*! @azure/msal-common v15.
|
|
6056
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6067
6057
|
|
|
6068
6058
|
/*
|
|
6069
6059
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6082,7 +6072,7 @@
|
|
|
6082
6072
|
}
|
|
6083
6073
|
}
|
|
6084
6074
|
|
|
6085
|
-
/*! @azure/msal-common v15.
|
|
6075
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6086
6076
|
/*
|
|
6087
6077
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6088
6078
|
* Licensed under the MIT License.
|
|
@@ -6103,7 +6093,7 @@
|
|
|
6103
6093
|
};
|
|
6104
6094
|
}
|
|
6105
6095
|
|
|
6106
|
-
/*! @azure/msal-common v15.
|
|
6096
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6107
6097
|
|
|
6108
6098
|
/*
|
|
6109
6099
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6190,7 +6180,7 @@
|
|
|
6190
6180
|
}
|
|
6191
6181
|
}
|
|
6192
6182
|
|
|
6193
|
-
/*! @azure/msal-common v15.
|
|
6183
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6194
6184
|
|
|
6195
6185
|
/*
|
|
6196
6186
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6221,7 +6211,7 @@
|
|
|
6221
6211
|
return new NetworkError(error, httpStatus, responseHeaders);
|
|
6222
6212
|
}
|
|
6223
6213
|
|
|
6224
|
-
/*! @azure/msal-common v15.
|
|
6214
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6225
6215
|
|
|
6226
6216
|
/*
|
|
6227
6217
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6369,7 +6359,7 @@
|
|
|
6369
6359
|
}
|
|
6370
6360
|
}
|
|
6371
6361
|
|
|
6372
|
-
/*! @azure/msal-common v15.
|
|
6362
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6373
6363
|
/*
|
|
6374
6364
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6375
6365
|
* Licensed under the MIT License.
|
|
@@ -6395,7 +6385,7 @@
|
|
|
6395
6385
|
refreshTokenExpired: refreshTokenExpired
|
|
6396
6386
|
});
|
|
6397
6387
|
|
|
6398
|
-
/*! @azure/msal-common v15.
|
|
6388
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6399
6389
|
|
|
6400
6390
|
/*
|
|
6401
6391
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6483,7 +6473,7 @@
|
|
|
6483
6473
|
return new InteractionRequiredAuthError(errorCode, InteractionRequiredAuthErrorMessages[errorCode]);
|
|
6484
6474
|
}
|
|
6485
6475
|
|
|
6486
|
-
/*! @azure/msal-common v15.
|
|
6476
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6487
6477
|
|
|
6488
6478
|
/*
|
|
6489
6479
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6555,7 +6545,7 @@
|
|
|
6555
6545
|
}
|
|
6556
6546
|
}
|
|
6557
6547
|
|
|
6558
|
-
/*! @azure/msal-common v15.
|
|
6548
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6559
6549
|
|
|
6560
6550
|
/*
|
|
6561
6551
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6639,7 +6629,7 @@
|
|
|
6639
6629
|
}
|
|
6640
6630
|
}
|
|
6641
6631
|
|
|
6642
|
-
/*! @azure/msal-common v15.
|
|
6632
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6643
6633
|
/*
|
|
6644
6634
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
6645
6635
|
* Licensed under the MIT License.
|
|
@@ -6666,7 +6656,7 @@
|
|
|
6666
6656
|
}
|
|
6667
6657
|
}
|
|
6668
6658
|
|
|
6669
|
-
/*! @azure/msal-common v15.
|
|
6659
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
6670
6660
|
|
|
6671
6661
|
/*
|
|
6672
6662
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -6997,7 +6987,7 @@
|
|
|
6997
6987
|
return baseAccount;
|
|
6998
6988
|
}
|
|
6999
6989
|
|
|
7000
|
-
/*! @azure/msal-common v15.
|
|
6990
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7001
6991
|
|
|
7002
6992
|
/*
|
|
7003
6993
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7064,7 +7054,7 @@
|
|
|
7064
7054
|
}
|
|
7065
7055
|
}
|
|
7066
7056
|
|
|
7067
|
-
/*! @azure/msal-common v15.
|
|
7057
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7068
7058
|
/*
|
|
7069
7059
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
7070
7060
|
* Licensed under the MIT License.
|
|
@@ -7082,7 +7072,7 @@
|
|
|
7082
7072
|
}
|
|
7083
7073
|
}
|
|
7084
7074
|
|
|
7085
|
-
/*! @azure/msal-common v15.
|
|
7075
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7086
7076
|
|
|
7087
7077
|
/*
|
|
7088
7078
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7315,7 +7305,7 @@
|
|
|
7315
7305
|
}
|
|
7316
7306
|
}
|
|
7317
7307
|
|
|
7318
|
-
/*! @azure/msal-common v15.
|
|
7308
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7319
7309
|
|
|
7320
7310
|
/*
|
|
7321
7311
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7524,7 +7514,7 @@
|
|
|
7524
7514
|
}
|
|
7525
7515
|
}
|
|
7526
7516
|
|
|
7527
|
-
/*! @azure/msal-common v15.
|
|
7517
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7528
7518
|
|
|
7529
7519
|
/*
|
|
7530
7520
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7622,7 +7612,7 @@
|
|
|
7622
7612
|
}
|
|
7623
7613
|
}
|
|
7624
7614
|
|
|
7625
|
-
/*! @azure/msal-common v15.
|
|
7615
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7626
7616
|
|
|
7627
7617
|
/*
|
|
7628
7618
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7637,7 +7627,7 @@
|
|
|
7637
7627
|
},
|
|
7638
7628
|
};
|
|
7639
7629
|
|
|
7640
|
-
/*! @azure/msal-common v15.
|
|
7630
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7641
7631
|
|
|
7642
7632
|
/*
|
|
7643
7633
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7861,7 +7851,7 @@
|
|
|
7861
7851
|
return account.idTokenClaims?.login_hint || null;
|
|
7862
7852
|
}
|
|
7863
7853
|
|
|
7864
|
-
/*! @azure/msal-common v15.
|
|
7854
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7865
7855
|
|
|
7866
7856
|
/*
|
|
7867
7857
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -7919,7 +7909,7 @@
|
|
|
7919
7909
|
}
|
|
7920
7910
|
}
|
|
7921
7911
|
|
|
7922
|
-
/*! @azure/msal-common v15.
|
|
7912
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
7923
7913
|
|
|
7924
7914
|
/*
|
|
7925
7915
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -8182,7 +8172,7 @@
|
|
|
8182
8172
|
}
|
|
8183
8173
|
}
|
|
8184
8174
|
|
|
8185
|
-
/*! @azure/msal-common v15.
|
|
8175
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8186
8176
|
/*
|
|
8187
8177
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
8188
8178
|
* Licensed under the MIT License.
|
|
@@ -8190,7 +8180,7 @@
|
|
|
8190
8180
|
const missingKidError = "missing_kid_error";
|
|
8191
8181
|
const missingAlgError = "missing_alg_error";
|
|
8192
8182
|
|
|
8193
|
-
/*! @azure/msal-common v15.
|
|
8183
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8194
8184
|
|
|
8195
8185
|
/*
|
|
8196
8186
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -8215,7 +8205,7 @@
|
|
|
8215
8205
|
return new JoseHeaderError(code, JoseHeaderErrorMessages[code]);
|
|
8216
8206
|
}
|
|
8217
8207
|
|
|
8218
|
-
/*! @azure/msal-common v15.
|
|
8208
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8219
8209
|
|
|
8220
8210
|
/*
|
|
8221
8211
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -8255,7 +8245,7 @@
|
|
|
8255
8245
|
}
|
|
8256
8246
|
}
|
|
8257
8247
|
|
|
8258
|
-
/*! @azure/msal-common v15.
|
|
8248
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8259
8249
|
|
|
8260
8250
|
/*
|
|
8261
8251
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -8334,7 +8324,7 @@
|
|
|
8334
8324
|
}
|
|
8335
8325
|
}
|
|
8336
8326
|
|
|
8337
|
-
/*! @azure/msal-common v15.
|
|
8327
|
+
/*! @azure/msal-common v15.7.0 2025-05-30 */
|
|
8338
8328
|
|
|
8339
8329
|
/*
|
|
8340
8330
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -9353,10 +9343,15 @@
|
|
|
9353
9343
|
*/
|
|
9354
9344
|
MSAL_SKU: "msal.js.browser",
|
|
9355
9345
|
};
|
|
9356
|
-
const
|
|
9346
|
+
const PlatformAuthConstants = {
|
|
9357
9347
|
CHANNEL_ID: "53ee284d-920a-4b59-9d30-a60315b26836",
|
|
9358
9348
|
PREFERRED_EXTENSION_ID: "ppnbnpeolgkicgegkbkbjmhlideopiji",
|
|
9359
9349
|
MATS_TELEMETRY: "MATS",
|
|
9350
|
+
MICROSOFT_ENTRA_BROKERID: "MicrosoftEntra",
|
|
9351
|
+
DOM_API_NAME: "DOM API",
|
|
9352
|
+
PLATFORM_DOM_APIS: "get-token-and-sign-out",
|
|
9353
|
+
PLATFORM_DOM_PROVIDER: "PlatformAuthDOMHandler",
|
|
9354
|
+
PLATFORM_EXTENSION_PROVIDER: "PlatformAuthExtensionHandler",
|
|
9360
9355
|
};
|
|
9361
9356
|
const NativeExtensionMethod = {
|
|
9362
9357
|
HandshakeRequest: "Handshake",
|
|
@@ -9394,6 +9389,7 @@
|
|
|
9394
9389
|
const StaticCacheKeys = {
|
|
9395
9390
|
ACCOUNT_KEYS: "msal.account.keys",
|
|
9396
9391
|
TOKEN_KEYS: "msal.token.keys",
|
|
9392
|
+
VERSION: "msal.version",
|
|
9397
9393
|
};
|
|
9398
9394
|
/**
|
|
9399
9395
|
* Cache keys stored in-memory
|
|
@@ -9522,7 +9518,8 @@
|
|
|
9522
9518
|
];
|
|
9523
9519
|
const LOG_LEVEL_CACHE_KEY = "msal.browser.log.level";
|
|
9524
9520
|
const LOG_PII_CACHE_KEY = "msal.browser.log.pii";
|
|
9525
|
-
const BROWSER_PERF_ENABLED_KEY = "msal.browser.performance.enabled";
|
|
9521
|
+
const BROWSER_PERF_ENABLED_KEY = "msal.browser.performance.enabled";
|
|
9522
|
+
const PLATFORM_AUTH_DOM_SUPPORT = "msal.browser.platform.auth.dom";
|
|
9526
9523
|
|
|
9527
9524
|
/*
|
|
9528
9525
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -10432,7 +10429,7 @@
|
|
|
10432
10429
|
|
|
10433
10430
|
/* eslint-disable header/header */
|
|
10434
10431
|
const name = "@azure/msal-browser";
|
|
10435
|
-
const version = "4.
|
|
10432
|
+
const version = "4.13.0";
|
|
10436
10433
|
|
|
10437
10434
|
/*
|
|
10438
10435
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
@@ -11784,6 +11781,7 @@
|
|
|
11784
11781
|
LOGOUT_FAILURE: "msal:logoutFailure",
|
|
11785
11782
|
LOGOUT_END: "msal:logoutEnd",
|
|
11786
11783
|
RESTORE_FROM_BFCACHE: "msal:restoreFromBFCache",
|
|
11784
|
+
BROKER_CONNECTION_ESTABLISHED: "msal:brokerConnectionEstablished",
|
|
11787
11785
|
};
|
|
11788
11786
|
|
|
11789
11787
|
/*
|
|
@@ -11809,6 +11807,20 @@
|
|
|
11809
11807
|
}
|
|
11810
11808
|
async initialize(correlationId) {
|
|
11811
11809
|
await this.browserStorage.initialize(correlationId);
|
|
11810
|
+
this.trackVersionChanges(correlationId);
|
|
11811
|
+
}
|
|
11812
|
+
/**
|
|
11813
|
+
* Tracks upgrades and downgrades for telemetry and debugging purposes
|
|
11814
|
+
*/
|
|
11815
|
+
trackVersionChanges(correlationId) {
|
|
11816
|
+
const previousVersion = this.browserStorage.getItem(StaticCacheKeys.VERSION);
|
|
11817
|
+
if (previousVersion) {
|
|
11818
|
+
this.logger.info(`MSAL.js was last initialized by version: ${previousVersion}`);
|
|
11819
|
+
this.performanceClient.addFields({ previousLibraryVersion: previousVersion }, correlationId);
|
|
11820
|
+
}
|
|
11821
|
+
if (previousVersion !== version) {
|
|
11822
|
+
this.browserStorage.setItem(StaticCacheKeys.VERSION, version);
|
|
11823
|
+
}
|
|
11812
11824
|
}
|
|
11813
11825
|
/**
|
|
11814
11826
|
* Parses passed value as JSON object, JSON.parse() will throw an error.
|
|
@@ -12529,7 +12541,17 @@
|
|
|
12529
12541
|
getInteractionInProgress() {
|
|
12530
12542
|
const key = `${Constants.CACHE_PREFIX}.${TemporaryCacheKeys.INTERACTION_STATUS_KEY}`;
|
|
12531
12543
|
const value = this.getTemporaryCache(key, false);
|
|
12532
|
-
|
|
12544
|
+
try {
|
|
12545
|
+
return value ? JSON.parse(value) : null;
|
|
12546
|
+
}
|
|
12547
|
+
catch (e) {
|
|
12548
|
+
// Remove interaction and other temp keys if interaction status can't be parsed
|
|
12549
|
+
this.logger.error(`Cannot parse interaction status. Removing temporary cache items and clearing url hash. Retrying interaction should fix the error`);
|
|
12550
|
+
this.removeTemporaryItem(key);
|
|
12551
|
+
this.resetRequestCache();
|
|
12552
|
+
clearHash(window);
|
|
12553
|
+
return null;
|
|
12554
|
+
}
|
|
12533
12555
|
}
|
|
12534
12556
|
setInteractionInProgress(inProgress, type = INTERACTION_TYPE.SIGNIN) {
|
|
12535
12557
|
// Ensure we don't overwrite interaction in progress for a different clientId
|
|
@@ -12878,14 +12900,14 @@
|
|
|
12878
12900
|
* Licensed under the MIT License.
|
|
12879
12901
|
*/
|
|
12880
12902
|
class BaseInteractionClient {
|
|
12881
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
12903
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthProvider, correlationId) {
|
|
12882
12904
|
this.config = config;
|
|
12883
12905
|
this.browserStorage = storageImpl;
|
|
12884
12906
|
this.browserCrypto = browserCrypto;
|
|
12885
12907
|
this.networkClient = this.config.system.networkClient;
|
|
12886
12908
|
this.eventHandler = eventHandler;
|
|
12887
12909
|
this.navigationClient = navigationClient;
|
|
12888
|
-
this.
|
|
12910
|
+
this.platformAuthProvider = platformAuthProvider;
|
|
12889
12911
|
this.correlationId = correlationId || createNewGuid();
|
|
12890
12912
|
this.logger = logger.clone(BrowserConstants.MSAL_SKU, version, this.correlationId);
|
|
12891
12913
|
this.performanceClient = performanceClient;
|
|
@@ -13241,6 +13263,159 @@
|
|
|
13241
13263
|
}
|
|
13242
13264
|
}
|
|
13243
13265
|
|
|
13266
|
+
/*
|
|
13267
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13268
|
+
* Licensed under the MIT License.
|
|
13269
|
+
*/
|
|
13270
|
+
/**
|
|
13271
|
+
* Extracts the BrowserStateObject from the state string.
|
|
13272
|
+
* @param browserCrypto
|
|
13273
|
+
* @param state
|
|
13274
|
+
*/
|
|
13275
|
+
function extractBrowserRequestState(browserCrypto, state) {
|
|
13276
|
+
if (!state) {
|
|
13277
|
+
return null;
|
|
13278
|
+
}
|
|
13279
|
+
try {
|
|
13280
|
+
const requestStateObj = ProtocolUtils.parseRequestState(browserCrypto, state);
|
|
13281
|
+
return requestStateObj.libraryState.meta;
|
|
13282
|
+
}
|
|
13283
|
+
catch (e) {
|
|
13284
|
+
throw createClientAuthError(invalidState);
|
|
13285
|
+
}
|
|
13286
|
+
}
|
|
13287
|
+
|
|
13288
|
+
/*
|
|
13289
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13290
|
+
* Licensed under the MIT License.
|
|
13291
|
+
*/
|
|
13292
|
+
function deserializeResponse(responseString, responseLocation, logger) {
|
|
13293
|
+
// Deserialize hash fragment response parameters.
|
|
13294
|
+
const serverParams = getDeserializedResponse(responseString);
|
|
13295
|
+
if (!serverParams) {
|
|
13296
|
+
if (!stripLeadingHashOrQuery(responseString)) {
|
|
13297
|
+
// Hash or Query string is empty
|
|
13298
|
+
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.`);
|
|
13299
|
+
throw createBrowserAuthError(hashEmptyError);
|
|
13300
|
+
}
|
|
13301
|
+
else {
|
|
13302
|
+
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.`);
|
|
13303
|
+
logger.errorPii(`The ${responseLocation} detected is: ${responseString}`);
|
|
13304
|
+
throw createBrowserAuthError(hashDoesNotContainKnownProperties);
|
|
13305
|
+
}
|
|
13306
|
+
}
|
|
13307
|
+
return serverParams;
|
|
13308
|
+
}
|
|
13309
|
+
/**
|
|
13310
|
+
* Returns the interaction type that the response object belongs to
|
|
13311
|
+
*/
|
|
13312
|
+
function validateInteractionType(response, browserCrypto, interactionType) {
|
|
13313
|
+
if (!response.state) {
|
|
13314
|
+
throw createBrowserAuthError(noStateInHash);
|
|
13315
|
+
}
|
|
13316
|
+
const platformStateObj = extractBrowserRequestState(browserCrypto, response.state);
|
|
13317
|
+
if (!platformStateObj) {
|
|
13318
|
+
throw createBrowserAuthError(unableToParseState);
|
|
13319
|
+
}
|
|
13320
|
+
if (platformStateObj.interactionType !== interactionType) {
|
|
13321
|
+
throw createBrowserAuthError(stateInteractionTypeMismatch);
|
|
13322
|
+
}
|
|
13323
|
+
}
|
|
13324
|
+
|
|
13325
|
+
/*
|
|
13326
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13327
|
+
* Licensed under the MIT License.
|
|
13328
|
+
*/
|
|
13329
|
+
/**
|
|
13330
|
+
* Abstract class which defines operations for a browser interaction handling class.
|
|
13331
|
+
*/
|
|
13332
|
+
class InteractionHandler {
|
|
13333
|
+
constructor(authCodeModule, storageImpl, authCodeRequest, logger, performanceClient) {
|
|
13334
|
+
this.authModule = authCodeModule;
|
|
13335
|
+
this.browserStorage = storageImpl;
|
|
13336
|
+
this.authCodeRequest = authCodeRequest;
|
|
13337
|
+
this.logger = logger;
|
|
13338
|
+
this.performanceClient = performanceClient;
|
|
13339
|
+
}
|
|
13340
|
+
/**
|
|
13341
|
+
* Function to handle response parameters from hash.
|
|
13342
|
+
* @param locationHash
|
|
13343
|
+
*/
|
|
13344
|
+
async handleCodeResponse(response, request) {
|
|
13345
|
+
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponse, request.correlationId);
|
|
13346
|
+
let authCodeResponse;
|
|
13347
|
+
try {
|
|
13348
|
+
authCodeResponse = getAuthorizationCodePayload(response, request.state);
|
|
13349
|
+
}
|
|
13350
|
+
catch (e) {
|
|
13351
|
+
if (e instanceof ServerError &&
|
|
13352
|
+
e.subError === userCancelled) {
|
|
13353
|
+
// Translate server error caused by user closing native prompt to corresponding first class MSAL error
|
|
13354
|
+
throw createBrowserAuthError(userCancelled);
|
|
13355
|
+
}
|
|
13356
|
+
else {
|
|
13357
|
+
throw e;
|
|
13358
|
+
}
|
|
13359
|
+
}
|
|
13360
|
+
return invokeAsync(this.handleCodeResponseFromServer.bind(this), PerformanceEvents.HandleCodeResponseFromServer, this.logger, this.performanceClient, request.correlationId)(authCodeResponse, request);
|
|
13361
|
+
}
|
|
13362
|
+
/**
|
|
13363
|
+
* Process auth code response from AAD
|
|
13364
|
+
* @param authCodeResponse
|
|
13365
|
+
* @param state
|
|
13366
|
+
* @param authority
|
|
13367
|
+
* @param networkModule
|
|
13368
|
+
* @returns
|
|
13369
|
+
*/
|
|
13370
|
+
async handleCodeResponseFromServer(authCodeResponse, request, validateNonce = true) {
|
|
13371
|
+
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponseFromServer, request.correlationId);
|
|
13372
|
+
this.logger.trace("InteractionHandler.handleCodeResponseFromServer called");
|
|
13373
|
+
// Assign code to request
|
|
13374
|
+
this.authCodeRequest.code = authCodeResponse.code;
|
|
13375
|
+
// Check for new cloud instance
|
|
13376
|
+
if (authCodeResponse.cloud_instance_host_name) {
|
|
13377
|
+
await invokeAsync(this.authModule.updateAuthority.bind(this.authModule), PerformanceEvents.UpdateTokenEndpointAuthority, this.logger, this.performanceClient, request.correlationId)(authCodeResponse.cloud_instance_host_name, request.correlationId);
|
|
13378
|
+
}
|
|
13379
|
+
// Nonce validation not needed when redirect not involved (e.g. hybrid spa, renewing token via rt)
|
|
13380
|
+
if (validateNonce) {
|
|
13381
|
+
// TODO: Assigning "response nonce" to "request nonce" is confusing. Refactor the function doing validation to accept request nonce directly
|
|
13382
|
+
authCodeResponse.nonce = request.nonce || undefined;
|
|
13383
|
+
}
|
|
13384
|
+
authCodeResponse.state = request.state;
|
|
13385
|
+
// Add CCS parameters if available
|
|
13386
|
+
if (authCodeResponse.client_info) {
|
|
13387
|
+
this.authCodeRequest.clientInfo = authCodeResponse.client_info;
|
|
13388
|
+
}
|
|
13389
|
+
else {
|
|
13390
|
+
const ccsCred = this.createCcsCredentials(request);
|
|
13391
|
+
if (ccsCred) {
|
|
13392
|
+
this.authCodeRequest.ccsCredential = ccsCred;
|
|
13393
|
+
}
|
|
13394
|
+
}
|
|
13395
|
+
// Acquire token with retrieved code.
|
|
13396
|
+
const tokenResponse = (await invokeAsync(this.authModule.acquireToken.bind(this.authModule), PerformanceEvents.AuthClientAcquireToken, this.logger, this.performanceClient, request.correlationId)(this.authCodeRequest, authCodeResponse));
|
|
13397
|
+
return tokenResponse;
|
|
13398
|
+
}
|
|
13399
|
+
/**
|
|
13400
|
+
* Build ccs creds if available
|
|
13401
|
+
*/
|
|
13402
|
+
createCcsCredentials(request) {
|
|
13403
|
+
if (request.account) {
|
|
13404
|
+
return {
|
|
13405
|
+
credential: request.account.homeAccountId,
|
|
13406
|
+
type: CcsCredentialType.HOME_ACCOUNT_ID,
|
|
13407
|
+
};
|
|
13408
|
+
}
|
|
13409
|
+
else if (request.loginHint) {
|
|
13410
|
+
return {
|
|
13411
|
+
credential: request.loginHint,
|
|
13412
|
+
type: CcsCredentialType.UPN,
|
|
13413
|
+
};
|
|
13414
|
+
}
|
|
13415
|
+
return null;
|
|
13416
|
+
}
|
|
13417
|
+
}
|
|
13418
|
+
|
|
13244
13419
|
/*
|
|
13245
13420
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13246
13421
|
* Licensed under the MIT License.
|
|
@@ -13325,930 +13500,1153 @@
|
|
|
13325
13500
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13326
13501
|
* Licensed under the MIT License.
|
|
13327
13502
|
*/
|
|
13328
|
-
class
|
|
13329
|
-
constructor(logger, handshakeTimeoutMs, performanceClient, extensionId) {
|
|
13330
|
-
this.logger = logger;
|
|
13331
|
-
this.handshakeTimeoutMs = handshakeTimeoutMs;
|
|
13332
|
-
this.extensionId = extensionId;
|
|
13333
|
-
this.resolvers = new Map(); // Used for non-handshake messages
|
|
13334
|
-
this.handshakeResolvers = new Map(); // Used for handshake messages
|
|
13335
|
-
this.messageChannel = new MessageChannel();
|
|
13336
|
-
this.windowListener = this.onWindowMessage.bind(this); // Window event callback doesn't have access to 'this' unless it's bound
|
|
13337
|
-
this.performanceClient = performanceClient;
|
|
13338
|
-
this.handshakeEvent = performanceClient.startMeasurement(PerformanceEvents.NativeMessageHandlerHandshake);
|
|
13339
|
-
}
|
|
13503
|
+
class SilentCacheClient extends StandardInteractionClient {
|
|
13340
13504
|
/**
|
|
13341
|
-
*
|
|
13342
|
-
* @param
|
|
13505
|
+
* Returns unexpired tokens from the cache, if available
|
|
13506
|
+
* @param silentRequest
|
|
13343
13507
|
*/
|
|
13344
|
-
async
|
|
13345
|
-
this.
|
|
13346
|
-
|
|
13347
|
-
|
|
13348
|
-
|
|
13349
|
-
|
|
13350
|
-
|
|
13351
|
-
|
|
13352
|
-
|
|
13353
|
-
this.logger.tracePii(`NativeMessageHandler - Sending request to browser extension: ${JSON.stringify(req)}`);
|
|
13354
|
-
this.messageChannel.port1.postMessage(req);
|
|
13355
|
-
return new Promise((resolve, reject) => {
|
|
13356
|
-
this.resolvers.set(req.responseId, { resolve, reject });
|
|
13508
|
+
async acquireToken(silentRequest) {
|
|
13509
|
+
this.performanceClient.addQueueMeasurement(PerformanceEvents.SilentCacheClientAcquireToken, silentRequest.correlationId);
|
|
13510
|
+
// Telemetry manager only used to increment cacheHits here
|
|
13511
|
+
const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenSilent_silentFlow);
|
|
13512
|
+
const clientConfig = await invokeAsync(this.getClientConfiguration.bind(this), PerformanceEvents.StandardInteractionClientGetClientConfiguration, this.logger, this.performanceClient, this.correlationId)({
|
|
13513
|
+
serverTelemetryManager,
|
|
13514
|
+
requestAuthority: silentRequest.authority,
|
|
13515
|
+
requestAzureCloudOptions: silentRequest.azureCloudOptions,
|
|
13516
|
+
account: silentRequest.account,
|
|
13357
13517
|
});
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
* Returns an instance of the MessageHandler that has successfully established a connection with an extension
|
|
13361
|
-
* @param {Logger} logger
|
|
13362
|
-
* @param {number} handshakeTimeoutMs
|
|
13363
|
-
* @param {IPerformanceClient} performanceClient
|
|
13364
|
-
* @param {ICrypto} crypto
|
|
13365
|
-
*/
|
|
13366
|
-
static async createProvider(logger, handshakeTimeoutMs, performanceClient) {
|
|
13367
|
-
logger.trace("NativeMessageHandler - createProvider called.");
|
|
13518
|
+
const silentAuthClient = new SilentFlowClient(clientConfig, this.performanceClient);
|
|
13519
|
+
this.logger.verbose("Silent auth client created");
|
|
13368
13520
|
try {
|
|
13369
|
-
const
|
|
13370
|
-
|
|
13371
|
-
|
|
13521
|
+
const response = await invokeAsync(silentAuthClient.acquireCachedToken.bind(silentAuthClient), PerformanceEvents.SilentFlowClientAcquireCachedToken, this.logger, this.performanceClient, silentRequest.correlationId)(silentRequest);
|
|
13522
|
+
const authResponse = response[0];
|
|
13523
|
+
this.performanceClient.addFields({
|
|
13524
|
+
fromCache: true,
|
|
13525
|
+
}, silentRequest.correlationId);
|
|
13526
|
+
return authResponse;
|
|
13372
13527
|
}
|
|
13373
|
-
catch (
|
|
13374
|
-
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
|
|
13528
|
+
catch (error) {
|
|
13529
|
+
if (error instanceof BrowserAuthError &&
|
|
13530
|
+
error.errorCode === cryptoKeyNotFound) {
|
|
13531
|
+
this.logger.verbose("Signing keypair for bound access token not found. Refreshing bound access token and generating a new crypto keypair.");
|
|
13532
|
+
}
|
|
13533
|
+
throw error;
|
|
13378
13534
|
}
|
|
13379
13535
|
}
|
|
13380
13536
|
/**
|
|
13381
|
-
*
|
|
13537
|
+
* API to silenty clear the browser cache.
|
|
13538
|
+
* @param logoutRequest
|
|
13382
13539
|
*/
|
|
13383
|
-
|
|
13384
|
-
this.logger.
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
this.
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
|
|
13405
|
-
|
|
13406
|
-
|
|
13407
|
-
|
|
13408
|
-
* This typically suggests an event handler stopped propagation of the Handshake request but did not respond to it on the MessageChannel port
|
|
13409
|
-
*/
|
|
13410
|
-
window.removeEventListener("message", this.windowListener, false);
|
|
13411
|
-
this.messageChannel.port1.close();
|
|
13412
|
-
this.messageChannel.port2.close();
|
|
13413
|
-
this.handshakeEvent.end({
|
|
13414
|
-
extensionHandshakeTimedOut: true,
|
|
13415
|
-
success: false,
|
|
13416
|
-
});
|
|
13417
|
-
reject(createBrowserAuthError(nativeHandshakeTimeout));
|
|
13418
|
-
this.handshakeResolvers.delete(req.responseId);
|
|
13419
|
-
}, this.handshakeTimeoutMs); // Use a reasonable timeout in milliseconds here
|
|
13540
|
+
logout(logoutRequest) {
|
|
13541
|
+
this.logger.verbose("logoutRedirect called");
|
|
13542
|
+
const validLogoutRequest = this.initializeLogoutRequest(logoutRequest);
|
|
13543
|
+
return this.clearCacheOnLogout(validLogoutRequest?.account);
|
|
13544
|
+
}
|
|
13545
|
+
}
|
|
13546
|
+
|
|
13547
|
+
/*
|
|
13548
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13549
|
+
* Licensed under the MIT License.
|
|
13550
|
+
*/
|
|
13551
|
+
class PlatformAuthInteractionClient extends BaseInteractionClient {
|
|
13552
|
+
constructor(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, provider, accountId, nativeStorageImpl, correlationId) {
|
|
13553
|
+
super(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13554
|
+
this.apiId = apiId;
|
|
13555
|
+
this.accountId = accountId;
|
|
13556
|
+
this.platformAuthProvider = provider;
|
|
13557
|
+
this.nativeStorageManager = nativeStorageImpl;
|
|
13558
|
+
this.silentCacheClient = new SilentCacheClient(config, this.nativeStorageManager, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13559
|
+
const extensionName = this.platformAuthProvider.getExtensionName();
|
|
13560
|
+
this.skus = ServerTelemetryManager.makeExtraSkuString({
|
|
13561
|
+
libraryName: BrowserConstants.MSAL_SKU,
|
|
13562
|
+
libraryVersion: version,
|
|
13563
|
+
extensionName: extensionName,
|
|
13564
|
+
extensionVersion: this.platformAuthProvider.getExtensionVersion(),
|
|
13420
13565
|
});
|
|
13421
13566
|
}
|
|
13422
13567
|
/**
|
|
13423
|
-
*
|
|
13424
|
-
* @param
|
|
13568
|
+
* Adds SKUs to request extra query parameters
|
|
13569
|
+
* @param request {PlatformAuthRequest}
|
|
13570
|
+
* @private
|
|
13425
13571
|
*/
|
|
13426
|
-
|
|
13427
|
-
|
|
13428
|
-
|
|
13429
|
-
|
|
13430
|
-
|
|
13431
|
-
}
|
|
13432
|
-
const request = event.data;
|
|
13433
|
-
if (!request.channel ||
|
|
13434
|
-
request.channel !== NativeConstants.CHANNEL_ID) {
|
|
13435
|
-
return;
|
|
13436
|
-
}
|
|
13437
|
-
if (request.extensionId && request.extensionId !== this.extensionId) {
|
|
13438
|
-
return;
|
|
13439
|
-
}
|
|
13440
|
-
if (request.body.method === NativeExtensionMethod.HandshakeRequest) {
|
|
13441
|
-
const handshakeResolver = this.handshakeResolvers.get(request.responseId);
|
|
13442
|
-
/*
|
|
13443
|
-
* Filter out responses with no matched resolvers sooner to keep channel ports open while waiting for
|
|
13444
|
-
* the proper response.
|
|
13445
|
-
*/
|
|
13446
|
-
if (!handshakeResolver) {
|
|
13447
|
-
this.logger.trace(`NativeMessageHandler.onWindowMessage - resolver can't be found for request ${request.responseId}`);
|
|
13448
|
-
return;
|
|
13449
|
-
}
|
|
13450
|
-
// If we receive this message back it means no extension intercepted the request, meaning no extension supporting handshake protocol is installed
|
|
13451
|
-
this.logger.verbose(request.extensionId
|
|
13452
|
-
? `Extension with id: ${request.extensionId} not installed`
|
|
13453
|
-
: "No extension installed");
|
|
13454
|
-
clearTimeout(this.timeoutId);
|
|
13455
|
-
this.messageChannel.port1.close();
|
|
13456
|
-
this.messageChannel.port2.close();
|
|
13457
|
-
window.removeEventListener("message", this.windowListener, false);
|
|
13458
|
-
this.handshakeEvent.end({
|
|
13459
|
-
success: false,
|
|
13460
|
-
extensionInstalled: false,
|
|
13461
|
-
});
|
|
13462
|
-
handshakeResolver.reject(createBrowserAuthError(nativeExtensionNotInstalled));
|
|
13463
|
-
}
|
|
13572
|
+
addRequestSKUs(request) {
|
|
13573
|
+
request.extraParameters = {
|
|
13574
|
+
...request.extraParameters,
|
|
13575
|
+
[X_CLIENT_EXTRA_SKU]: this.skus,
|
|
13576
|
+
};
|
|
13464
13577
|
}
|
|
13465
13578
|
/**
|
|
13466
|
-
*
|
|
13467
|
-
* @param
|
|
13579
|
+
* Acquire token from native platform via browser extension
|
|
13580
|
+
* @param request
|
|
13468
13581
|
*/
|
|
13469
|
-
|
|
13470
|
-
this.
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
const
|
|
13582
|
+
async acquireToken(request, cacheLookupPolicy) {
|
|
13583
|
+
this.performanceClient.addQueueMeasurement(PerformanceEvents.NativeInteractionClientAcquireToken, request.correlationId);
|
|
13584
|
+
this.logger.trace("NativeInteractionClient - acquireToken called.");
|
|
13585
|
+
// start the perf measurement
|
|
13586
|
+
const nativeATMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.NativeInteractionClientAcquireToken, request.correlationId);
|
|
13587
|
+
const reqTimestamp = nowSeconds();
|
|
13588
|
+
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
13474
13589
|
try {
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
else if (response.result) {
|
|
13487
|
-
if (response.result["code"] &&
|
|
13488
|
-
response.result["description"]) {
|
|
13489
|
-
resolver.reject(createNativeAuthError(response.result["code"], response.result["description"], response.result["ext"]));
|
|
13490
|
-
}
|
|
13491
|
-
else {
|
|
13492
|
-
resolver.resolve(response.result);
|
|
13493
|
-
}
|
|
13494
|
-
}
|
|
13495
|
-
else {
|
|
13496
|
-
throw createAuthError(unexpectedError, "Event does not contain result.");
|
|
13497
|
-
}
|
|
13498
|
-
this.resolvers.delete(request.responseId);
|
|
13590
|
+
// initialize native request
|
|
13591
|
+
const nativeRequest = await this.initializeNativeRequest(request);
|
|
13592
|
+
// check if the tokens can be retrieved from internal cache
|
|
13593
|
+
try {
|
|
13594
|
+
const result = await this.acquireTokensFromCache(this.accountId, nativeRequest);
|
|
13595
|
+
nativeATMeasurement.end({
|
|
13596
|
+
success: true,
|
|
13597
|
+
isNativeBroker: false,
|
|
13598
|
+
fromCache: true,
|
|
13599
|
+
});
|
|
13600
|
+
return result;
|
|
13499
13601
|
}
|
|
13500
|
-
|
|
13501
|
-
if (
|
|
13502
|
-
this.logger.
|
|
13503
|
-
|
|
13602
|
+
catch (e) {
|
|
13603
|
+
if (cacheLookupPolicy === CacheLookupPolicy.AccessToken) {
|
|
13604
|
+
this.logger.info("MSAL internal Cache does not contain tokens, return error as per cache policy");
|
|
13605
|
+
throw e;
|
|
13504
13606
|
}
|
|
13505
|
-
|
|
13506
|
-
|
|
13507
|
-
|
|
13508
|
-
|
|
13509
|
-
|
|
13510
|
-
|
|
13511
|
-
|
|
13607
|
+
// continue with a native call for any and all errors
|
|
13608
|
+
this.logger.info("MSAL internal Cache does not contain tokens, proceed to make a native call");
|
|
13609
|
+
}
|
|
13610
|
+
const validatedResponse = await this.platformAuthProvider.sendMessage(nativeRequest);
|
|
13611
|
+
return await this.handleNativeResponse(validatedResponse, nativeRequest, reqTimestamp)
|
|
13612
|
+
.then((result) => {
|
|
13613
|
+
nativeATMeasurement.end({
|
|
13512
13614
|
success: true,
|
|
13615
|
+
isNativeBroker: true,
|
|
13616
|
+
requestId: result.requestId,
|
|
13513
13617
|
});
|
|
13514
|
-
|
|
13515
|
-
|
|
13516
|
-
}
|
|
13517
|
-
|
|
13618
|
+
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
13619
|
+
return result;
|
|
13620
|
+
})
|
|
13621
|
+
.catch((error) => {
|
|
13622
|
+
nativeATMeasurement.end({
|
|
13623
|
+
success: false,
|
|
13624
|
+
errorCode: error.errorCode,
|
|
13625
|
+
subErrorCode: error.subError,
|
|
13626
|
+
isNativeBroker: true,
|
|
13627
|
+
});
|
|
13628
|
+
throw error;
|
|
13629
|
+
});
|
|
13518
13630
|
}
|
|
13519
|
-
catch (
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
this.logger.errorPii(`Unable to parse ${event}`);
|
|
13523
|
-
if (resolver) {
|
|
13524
|
-
resolver.reject(err);
|
|
13525
|
-
}
|
|
13526
|
-
else if (handshakeResolver) {
|
|
13527
|
-
handshakeResolver.reject(err);
|
|
13631
|
+
catch (e) {
|
|
13632
|
+
if (e instanceof NativeAuthError) {
|
|
13633
|
+
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
|
|
13528
13634
|
}
|
|
13635
|
+
throw e;
|
|
13529
13636
|
}
|
|
13530
13637
|
}
|
|
13531
13638
|
/**
|
|
13532
|
-
*
|
|
13533
|
-
* @
|
|
13639
|
+
* Creates silent flow request
|
|
13640
|
+
* @param request
|
|
13641
|
+
* @param cachedAccount
|
|
13642
|
+
* @returns CommonSilentFlowRequest
|
|
13534
13643
|
*/
|
|
13535
|
-
|
|
13536
|
-
return
|
|
13644
|
+
createSilentCacheRequest(request, cachedAccount) {
|
|
13645
|
+
return {
|
|
13646
|
+
authority: request.authority,
|
|
13647
|
+
correlationId: this.correlationId,
|
|
13648
|
+
scopes: ScopeSet.fromString(request.scope).asArray(),
|
|
13649
|
+
account: cachedAccount,
|
|
13650
|
+
forceRefresh: false,
|
|
13651
|
+
};
|
|
13537
13652
|
}
|
|
13538
13653
|
/**
|
|
13539
|
-
*
|
|
13540
|
-
* @
|
|
13654
|
+
* Fetches the tokens from the cache if un-expired
|
|
13655
|
+
* @param nativeAccountId
|
|
13656
|
+
* @param request
|
|
13657
|
+
* @returns authenticationResult
|
|
13541
13658
|
*/
|
|
13542
|
-
|
|
13543
|
-
|
|
13659
|
+
async acquireTokensFromCache(nativeAccountId, request) {
|
|
13660
|
+
if (!nativeAccountId) {
|
|
13661
|
+
this.logger.warning("NativeInteractionClient:acquireTokensFromCache - No nativeAccountId provided");
|
|
13662
|
+
throw createClientAuthError(noAccountFound);
|
|
13663
|
+
}
|
|
13664
|
+
// fetch the account from browser cache
|
|
13665
|
+
const account = this.browserStorage.getBaseAccountInfo({
|
|
13666
|
+
nativeAccountId,
|
|
13667
|
+
});
|
|
13668
|
+
if (!account) {
|
|
13669
|
+
throw createClientAuthError(noAccountFound);
|
|
13670
|
+
}
|
|
13671
|
+
// leverage silent flow for cached tokens retrieval
|
|
13672
|
+
try {
|
|
13673
|
+
const silentRequest = this.createSilentCacheRequest(request, account);
|
|
13674
|
+
const result = await this.silentCacheClient.acquireToken(silentRequest);
|
|
13675
|
+
const fullAccount = {
|
|
13676
|
+
...account,
|
|
13677
|
+
idTokenClaims: result?.idTokenClaims,
|
|
13678
|
+
idToken: result?.idToken,
|
|
13679
|
+
};
|
|
13680
|
+
return {
|
|
13681
|
+
...result,
|
|
13682
|
+
account: fullAccount,
|
|
13683
|
+
};
|
|
13684
|
+
}
|
|
13685
|
+
catch (e) {
|
|
13686
|
+
throw e;
|
|
13687
|
+
}
|
|
13544
13688
|
}
|
|
13545
13689
|
/**
|
|
13546
|
-
*
|
|
13547
|
-
* @param
|
|
13548
|
-
* @param
|
|
13549
|
-
* @param nativeExtensionProvider
|
|
13550
|
-
* @param authenticationScheme
|
|
13690
|
+
* Acquires a token from native platform then redirects to the redirectUri instead of returning the response
|
|
13691
|
+
* @param {RedirectRequest} request
|
|
13692
|
+
* @param {InProgressPerformanceEvent} rootMeasurement
|
|
13551
13693
|
*/
|
|
13552
|
-
|
|
13553
|
-
logger.trace("
|
|
13554
|
-
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
|
|
13558
|
-
|
|
13559
|
-
if (!nativeExtensionProvider) {
|
|
13560
|
-
logger.trace("isPlatformBrokerAvailable: Platform extension provider is not initialized, returning false");
|
|
13561
|
-
// Extension is not available
|
|
13562
|
-
return false;
|
|
13694
|
+
async acquireTokenRedirect(request, rootMeasurement) {
|
|
13695
|
+
this.logger.trace("NativeInteractionClient - acquireTokenRedirect called.");
|
|
13696
|
+
const { ...remainingParameters } = request;
|
|
13697
|
+
delete remainingParameters.onRedirectNavigate;
|
|
13698
|
+
const nativeRequest = await this.initializeNativeRequest(remainingParameters);
|
|
13699
|
+
try {
|
|
13700
|
+
await this.platformAuthProvider.sendMessage(nativeRequest);
|
|
13563
13701
|
}
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
|
|
13570
|
-
|
|
13571
|
-
|
|
13572
|
-
return false;
|
|
13702
|
+
catch (e) {
|
|
13703
|
+
// Only throw fatal errors here to allow application to fallback to regular redirect. Otherwise proceed and the error will be thrown in handleRedirectPromise
|
|
13704
|
+
if (e instanceof NativeAuthError) {
|
|
13705
|
+
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
13706
|
+
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
|
|
13707
|
+
if (isFatalNativeAuthError(e)) {
|
|
13708
|
+
throw e;
|
|
13709
|
+
}
|
|
13573
13710
|
}
|
|
13574
13711
|
}
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
|
|
13584
|
-
|
|
13585
|
-
|
|
13586
|
-
* @param state
|
|
13587
|
-
*/
|
|
13588
|
-
function extractBrowserRequestState(browserCrypto, state) {
|
|
13589
|
-
if (!state) {
|
|
13590
|
-
return null;
|
|
13591
|
-
}
|
|
13592
|
-
try {
|
|
13593
|
-
const requestStateObj = ProtocolUtils.parseRequestState(browserCrypto, state);
|
|
13594
|
-
return requestStateObj.libraryState.meta;
|
|
13595
|
-
}
|
|
13596
|
-
catch (e) {
|
|
13597
|
-
throw createClientAuthError(invalidState);
|
|
13598
|
-
}
|
|
13599
|
-
}
|
|
13600
|
-
|
|
13601
|
-
/*
|
|
13602
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13603
|
-
* Licensed under the MIT License.
|
|
13604
|
-
*/
|
|
13605
|
-
function deserializeResponse(responseString, responseLocation, logger) {
|
|
13606
|
-
// Deserialize hash fragment response parameters.
|
|
13607
|
-
const serverParams = getDeserializedResponse(responseString);
|
|
13608
|
-
if (!serverParams) {
|
|
13609
|
-
if (!stripLeadingHashOrQuery(responseString)) {
|
|
13610
|
-
// Hash or Query string is empty
|
|
13611
|
-
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.`);
|
|
13612
|
-
throw createBrowserAuthError(hashEmptyError);
|
|
13613
|
-
}
|
|
13614
|
-
else {
|
|
13615
|
-
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.`);
|
|
13616
|
-
logger.errorPii(`The ${responseLocation} detected is: ${responseString}`);
|
|
13617
|
-
throw createBrowserAuthError(hashDoesNotContainKnownProperties);
|
|
13618
|
-
}
|
|
13619
|
-
}
|
|
13620
|
-
return serverParams;
|
|
13621
|
-
}
|
|
13622
|
-
/**
|
|
13623
|
-
* Returns the interaction type that the response object belongs to
|
|
13624
|
-
*/
|
|
13625
|
-
function validateInteractionType(response, browserCrypto, interactionType) {
|
|
13626
|
-
if (!response.state) {
|
|
13627
|
-
throw createBrowserAuthError(noStateInHash);
|
|
13628
|
-
}
|
|
13629
|
-
const platformStateObj = extractBrowserRequestState(browserCrypto, response.state);
|
|
13630
|
-
if (!platformStateObj) {
|
|
13631
|
-
throw createBrowserAuthError(unableToParseState);
|
|
13632
|
-
}
|
|
13633
|
-
if (platformStateObj.interactionType !== interactionType) {
|
|
13634
|
-
throw createBrowserAuthError(stateInteractionTypeMismatch);
|
|
13635
|
-
}
|
|
13636
|
-
}
|
|
13637
|
-
|
|
13638
|
-
/*
|
|
13639
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13640
|
-
* Licensed under the MIT License.
|
|
13641
|
-
*/
|
|
13642
|
-
/**
|
|
13643
|
-
* Abstract class which defines operations for a browser interaction handling class.
|
|
13644
|
-
*/
|
|
13645
|
-
class InteractionHandler {
|
|
13646
|
-
constructor(authCodeModule, storageImpl, authCodeRequest, logger, performanceClient) {
|
|
13647
|
-
this.authModule = authCodeModule;
|
|
13648
|
-
this.browserStorage = storageImpl;
|
|
13649
|
-
this.authCodeRequest = authCodeRequest;
|
|
13650
|
-
this.logger = logger;
|
|
13651
|
-
this.performanceClient = performanceClient;
|
|
13712
|
+
this.browserStorage.setTemporaryCache(TemporaryCacheKeys.NATIVE_REQUEST, JSON.stringify(nativeRequest), true);
|
|
13713
|
+
const navigationOptions = {
|
|
13714
|
+
apiId: ApiId.acquireTokenRedirect,
|
|
13715
|
+
timeout: this.config.system.redirectNavigationTimeout,
|
|
13716
|
+
noHistory: false,
|
|
13717
|
+
};
|
|
13718
|
+
const redirectUri = this.config.auth.navigateToLoginRequestUrl
|
|
13719
|
+
? window.location.href
|
|
13720
|
+
: this.getRedirectUri(request.redirectUri);
|
|
13721
|
+
rootMeasurement.end({ success: true });
|
|
13722
|
+
await this.navigationClient.navigateExternal(redirectUri, navigationOptions); // Need to treat this as external to ensure handleRedirectPromise is run again
|
|
13652
13723
|
}
|
|
13653
13724
|
/**
|
|
13654
|
-
*
|
|
13655
|
-
* @param
|
|
13725
|
+
* If the previous page called native platform for a token using redirect APIs, send the same request again and return the response
|
|
13726
|
+
* @param performanceClient {IPerformanceClient?}
|
|
13727
|
+
* @param correlationId {string?} correlation identifier
|
|
13656
13728
|
*/
|
|
13657
|
-
async
|
|
13658
|
-
this.
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
|
|
13729
|
+
async handleRedirectPromise(performanceClient, correlationId) {
|
|
13730
|
+
this.logger.trace("NativeInteractionClient - handleRedirectPromise called.");
|
|
13731
|
+
if (!this.browserStorage.isInteractionInProgress(true)) {
|
|
13732
|
+
this.logger.info("handleRedirectPromise called but there is no interaction in progress, returning null.");
|
|
13733
|
+
return null;
|
|
13662
13734
|
}
|
|
13663
|
-
|
|
13664
|
-
|
|
13665
|
-
|
|
13666
|
-
|
|
13667
|
-
|
|
13668
|
-
|
|
13669
|
-
else {
|
|
13670
|
-
throw e;
|
|
13735
|
+
// remove prompt from the request to prevent WAM from prompting twice
|
|
13736
|
+
const cachedRequest = this.browserStorage.getCachedNativeRequest();
|
|
13737
|
+
if (!cachedRequest) {
|
|
13738
|
+
this.logger.verbose("NativeInteractionClient - handleRedirectPromise called but there is no cached request, returning null.");
|
|
13739
|
+
if (performanceClient && correlationId) {
|
|
13740
|
+
performanceClient?.addFields({ errorCode: "no_cached_request" }, correlationId);
|
|
13671
13741
|
}
|
|
13742
|
+
return null;
|
|
13672
13743
|
}
|
|
13673
|
-
|
|
13674
|
-
|
|
13675
|
-
|
|
13676
|
-
* Process auth code response from AAD
|
|
13677
|
-
* @param authCodeResponse
|
|
13678
|
-
* @param state
|
|
13679
|
-
* @param authority
|
|
13680
|
-
* @param networkModule
|
|
13681
|
-
* @returns
|
|
13682
|
-
*/
|
|
13683
|
-
async handleCodeResponseFromServer(authCodeResponse, request, validateNonce = true) {
|
|
13684
|
-
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponseFromServer, request.correlationId);
|
|
13685
|
-
this.logger.trace("InteractionHandler.handleCodeResponseFromServer called");
|
|
13686
|
-
// Assign code to request
|
|
13687
|
-
this.authCodeRequest.code = authCodeResponse.code;
|
|
13688
|
-
// Check for new cloud instance
|
|
13689
|
-
if (authCodeResponse.cloud_instance_host_name) {
|
|
13690
|
-
await invokeAsync(this.authModule.updateAuthority.bind(this.authModule), PerformanceEvents.UpdateTokenEndpointAuthority, this.logger, this.performanceClient, request.correlationId)(authCodeResponse.cloud_instance_host_name, request.correlationId);
|
|
13691
|
-
}
|
|
13692
|
-
// Nonce validation not needed when redirect not involved (e.g. hybrid spa, renewing token via rt)
|
|
13693
|
-
if (validateNonce) {
|
|
13694
|
-
// TODO: Assigning "response nonce" to "request nonce" is confusing. Refactor the function doing validation to accept request nonce directly
|
|
13695
|
-
authCodeResponse.nonce = request.nonce || undefined;
|
|
13744
|
+
const { prompt, ...request } = cachedRequest;
|
|
13745
|
+
if (prompt) {
|
|
13746
|
+
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.");
|
|
13696
13747
|
}
|
|
13697
|
-
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
this.
|
|
13748
|
+
this.browserStorage.removeItem(this.browserStorage.generateCacheKey(TemporaryCacheKeys.NATIVE_REQUEST));
|
|
13749
|
+
const reqTimestamp = nowSeconds();
|
|
13750
|
+
try {
|
|
13751
|
+
this.logger.verbose("NativeInteractionClient - handleRedirectPromise sending message to native broker.");
|
|
13752
|
+
const response = await this.platformAuthProvider.sendMessage(request);
|
|
13753
|
+
const authResult = await this.handleNativeResponse(response, request, reqTimestamp);
|
|
13754
|
+
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
13755
|
+
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
13756
|
+
return authResult;
|
|
13701
13757
|
}
|
|
13702
|
-
|
|
13703
|
-
|
|
13704
|
-
if (ccsCred) {
|
|
13705
|
-
this.authCodeRequest.ccsCredential = ccsCred;
|
|
13706
|
-
}
|
|
13758
|
+
catch (e) {
|
|
13759
|
+
throw e;
|
|
13707
13760
|
}
|
|
13708
|
-
// Acquire token with retrieved code.
|
|
13709
|
-
const tokenResponse = (await invokeAsync(this.authModule.acquireToken.bind(this.authModule), PerformanceEvents.AuthClientAcquireToken, this.logger, this.performanceClient, request.correlationId)(this.authCodeRequest, authCodeResponse));
|
|
13710
|
-
return tokenResponse;
|
|
13711
13761
|
}
|
|
13712
13762
|
/**
|
|
13713
|
-
*
|
|
13763
|
+
* Logout from native platform via browser extension
|
|
13764
|
+
* @param request
|
|
13714
13765
|
*/
|
|
13715
|
-
|
|
13716
|
-
|
|
13717
|
-
|
|
13718
|
-
credential: request.account.homeAccountId,
|
|
13719
|
-
type: CcsCredentialType.HOME_ACCOUNT_ID,
|
|
13720
|
-
};
|
|
13721
|
-
}
|
|
13722
|
-
else if (request.loginHint) {
|
|
13723
|
-
return {
|
|
13724
|
-
credential: request.loginHint,
|
|
13725
|
-
type: CcsCredentialType.UPN,
|
|
13726
|
-
};
|
|
13727
|
-
}
|
|
13728
|
-
return null;
|
|
13766
|
+
logout() {
|
|
13767
|
+
this.logger.trace("NativeInteractionClient - logout called.");
|
|
13768
|
+
return Promise.reject("Logout not implemented yet");
|
|
13729
13769
|
}
|
|
13730
|
-
}
|
|
13731
|
-
|
|
13732
|
-
/*
|
|
13733
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13734
|
-
* Licensed under the MIT License.
|
|
13735
|
-
*/
|
|
13736
|
-
class SilentCacheClient extends StandardInteractionClient {
|
|
13737
13770
|
/**
|
|
13738
|
-
*
|
|
13739
|
-
* @param
|
|
13771
|
+
* Transform response from native platform into AuthenticationResult object which will be returned to the end user
|
|
13772
|
+
* @param response
|
|
13773
|
+
* @param request
|
|
13774
|
+
* @param reqTimestamp
|
|
13740
13775
|
*/
|
|
13741
|
-
async
|
|
13742
|
-
this.
|
|
13743
|
-
//
|
|
13744
|
-
const
|
|
13745
|
-
const
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
13749
|
-
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
|
|
13753
|
-
try {
|
|
13754
|
-
const response = await invokeAsync(silentAuthClient.acquireCachedToken.bind(silentAuthClient), PerformanceEvents.SilentFlowClientAcquireCachedToken, this.logger, this.performanceClient, silentRequest.correlationId)(silentRequest);
|
|
13755
|
-
const authResponse = response[0];
|
|
13756
|
-
this.performanceClient.addFields({
|
|
13757
|
-
fromCache: true,
|
|
13758
|
-
}, silentRequest.correlationId);
|
|
13759
|
-
return authResponse;
|
|
13776
|
+
async handleNativeResponse(response, request, reqTimestamp) {
|
|
13777
|
+
this.logger.trace("NativeInteractionClient - handleNativeResponse called.");
|
|
13778
|
+
// generate identifiers
|
|
13779
|
+
const idTokenClaims = extractTokenClaims(response.id_token, base64Decode);
|
|
13780
|
+
const homeAccountIdentifier = this.createHomeAccountIdentifier(response, idTokenClaims);
|
|
13781
|
+
const cachedhomeAccountId = this.browserStorage.getAccountInfoFilteredBy({
|
|
13782
|
+
nativeAccountId: request.accountId,
|
|
13783
|
+
})?.homeAccountId;
|
|
13784
|
+
// add exception for double brokering, please note this is temporary and will be fortified in future
|
|
13785
|
+
if (request.extraParameters?.child_client_id &&
|
|
13786
|
+
response.account.id !== request.accountId) {
|
|
13787
|
+
this.logger.info("handleNativeServerResponse: Double broker flow detected, ignoring accountId mismatch");
|
|
13760
13788
|
}
|
|
13761
|
-
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
}
|
|
13766
|
-
throw error;
|
|
13789
|
+
else if (homeAccountIdentifier !== cachedhomeAccountId &&
|
|
13790
|
+
response.account.id !== request.accountId) {
|
|
13791
|
+
// 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
|
|
13792
|
+
throw createNativeAuthError(userSwitch);
|
|
13767
13793
|
}
|
|
13794
|
+
// Get the preferred_cache domain for the given authority
|
|
13795
|
+
const authority = await this.getDiscoveredAuthority({
|
|
13796
|
+
requestAuthority: request.authority,
|
|
13797
|
+
});
|
|
13798
|
+
const baseAccount = buildAccountToCache(this.browserStorage, authority, homeAccountIdentifier, base64Decode, idTokenClaims, response.client_info, undefined, // environment
|
|
13799
|
+
idTokenClaims.tid, undefined, // auth code payload
|
|
13800
|
+
response.account.id, this.logger);
|
|
13801
|
+
// Ensure expires_in is in number format
|
|
13802
|
+
response.expires_in = Number(response.expires_in);
|
|
13803
|
+
// generate authenticationResult
|
|
13804
|
+
const result = await this.generateAuthenticationResult(response, request, idTokenClaims, baseAccount, authority.canonicalAuthority, reqTimestamp);
|
|
13805
|
+
// cache accounts and tokens in the appropriate storage
|
|
13806
|
+
await this.cacheAccount(baseAccount);
|
|
13807
|
+
await this.cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, response.access_token, result.tenantId, reqTimestamp);
|
|
13808
|
+
return result;
|
|
13768
13809
|
}
|
|
13769
13810
|
/**
|
|
13770
|
-
*
|
|
13771
|
-
* @param
|
|
13811
|
+
* creates an homeAccountIdentifier for the account
|
|
13812
|
+
* @param response
|
|
13813
|
+
* @param idTokenObj
|
|
13814
|
+
* @returns
|
|
13772
13815
|
*/
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
const
|
|
13776
|
-
return
|
|
13777
|
-
}
|
|
13778
|
-
}
|
|
13779
|
-
|
|
13780
|
-
/*
|
|
13781
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13782
|
-
* Licensed under the MIT License.
|
|
13783
|
-
*/
|
|
13784
|
-
class NativeInteractionClient extends BaseInteractionClient {
|
|
13785
|
-
constructor(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, provider, accountId, nativeStorageImpl, correlationId) {
|
|
13786
|
-
super(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13787
|
-
this.apiId = apiId;
|
|
13788
|
-
this.accountId = accountId;
|
|
13789
|
-
this.nativeMessageHandler = provider;
|
|
13790
|
-
this.nativeStorageManager = nativeStorageImpl;
|
|
13791
|
-
this.silentCacheClient = new SilentCacheClient(config, this.nativeStorageManager, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13792
|
-
const extensionName = this.nativeMessageHandler.getExtensionId() ===
|
|
13793
|
-
NativeConstants.PREFERRED_EXTENSION_ID
|
|
13794
|
-
? "chrome"
|
|
13795
|
-
: this.nativeMessageHandler.getExtensionId()?.length
|
|
13796
|
-
? "unknown"
|
|
13797
|
-
: undefined;
|
|
13798
|
-
this.skus = ServerTelemetryManager.makeExtraSkuString({
|
|
13799
|
-
libraryName: BrowserConstants.MSAL_SKU,
|
|
13800
|
-
libraryVersion: version,
|
|
13801
|
-
extensionName: extensionName,
|
|
13802
|
-
extensionVersion: this.nativeMessageHandler.getExtensionVersion(),
|
|
13803
|
-
});
|
|
13816
|
+
createHomeAccountIdentifier(response, idTokenClaims) {
|
|
13817
|
+
// Save account in browser storage
|
|
13818
|
+
const homeAccountIdentifier = AccountEntity.generateHomeAccountId(response.client_info || Constants.EMPTY_STRING, AuthorityType.Default, this.logger, this.browserCrypto, idTokenClaims);
|
|
13819
|
+
return homeAccountIdentifier;
|
|
13804
13820
|
}
|
|
13805
13821
|
/**
|
|
13806
|
-
*
|
|
13807
|
-
* @param
|
|
13808
|
-
* @
|
|
13822
|
+
* Helper to generate scopes
|
|
13823
|
+
* @param response
|
|
13824
|
+
* @param request
|
|
13825
|
+
* @returns
|
|
13809
13826
|
*/
|
|
13810
|
-
|
|
13811
|
-
|
|
13812
|
-
|
|
13813
|
-
|
|
13814
|
-
};
|
|
13827
|
+
generateScopes(requestScopes, responseScopes) {
|
|
13828
|
+
return responseScopes
|
|
13829
|
+
? ScopeSet.fromString(responseScopes)
|
|
13830
|
+
: ScopeSet.fromString(requestScopes);
|
|
13815
13831
|
}
|
|
13816
13832
|
/**
|
|
13817
|
-
*
|
|
13833
|
+
* If PoP token is requesred, records the PoP token if returned from the WAM, else generates one in the browser
|
|
13818
13834
|
* @param request
|
|
13835
|
+
* @param response
|
|
13819
13836
|
*/
|
|
13820
|
-
async
|
|
13821
|
-
|
|
13822
|
-
|
|
13823
|
-
|
|
13824
|
-
|
|
13825
|
-
|
|
13826
|
-
|
|
13827
|
-
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
|
|
13831
|
-
try {
|
|
13832
|
-
const result = await this.acquireTokensFromCache(this.accountId, nativeRequest);
|
|
13833
|
-
nativeATMeasurement.end({
|
|
13834
|
-
success: true,
|
|
13835
|
-
isNativeBroker: false,
|
|
13836
|
-
fromCache: true,
|
|
13837
|
-
});
|
|
13838
|
-
return result;
|
|
13839
|
-
}
|
|
13840
|
-
catch (e) {
|
|
13841
|
-
if (cacheLookupPolicy === CacheLookupPolicy.AccessToken) {
|
|
13842
|
-
this.logger.info("MSAL internal Cache does not contain tokens, return error as per cache policy");
|
|
13843
|
-
throw e;
|
|
13844
|
-
}
|
|
13845
|
-
// continue with a native call for any and all errors
|
|
13846
|
-
this.logger.info("MSAL internal Cache does not contain tokens, proceed to make a native call");
|
|
13837
|
+
async generatePopAccessToken(response, request) {
|
|
13838
|
+
if (request.tokenType === AuthenticationScheme.POP &&
|
|
13839
|
+
request.signPopToken) {
|
|
13840
|
+
/**
|
|
13841
|
+
* This code prioritizes SHR returned from the native layer. In case of error/SHR not calculated from WAM and the AT
|
|
13842
|
+
* is still received, SHR is calculated locally
|
|
13843
|
+
*/
|
|
13844
|
+
// Check if native layer returned an SHR token
|
|
13845
|
+
if (response.shr) {
|
|
13846
|
+
this.logger.trace("handleNativeServerResponse: SHR is enabled in native layer");
|
|
13847
|
+
return response.shr;
|
|
13847
13848
|
}
|
|
13848
|
-
|
|
13849
|
-
|
|
13850
|
-
const
|
|
13851
|
-
|
|
13852
|
-
|
|
13849
|
+
// Generate SHR in msal js if WAM does not compute it when POP is enabled
|
|
13850
|
+
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto);
|
|
13851
|
+
const shrParameters = {
|
|
13852
|
+
resourceRequestMethod: request.resourceRequestMethod,
|
|
13853
|
+
resourceRequestUri: request.resourceRequestUri,
|
|
13854
|
+
shrClaims: request.shrClaims,
|
|
13855
|
+
shrNonce: request.shrNonce,
|
|
13853
13856
|
};
|
|
13854
|
-
|
|
13855
|
-
|
|
13856
|
-
|
|
13857
|
-
|
|
13858
|
-
|
|
13859
|
-
|
|
13860
|
-
isNativeBroker: true,
|
|
13861
|
-
requestId: result.requestId,
|
|
13862
|
-
});
|
|
13863
|
-
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
13864
|
-
return result;
|
|
13865
|
-
})
|
|
13866
|
-
.catch((error) => {
|
|
13867
|
-
nativeATMeasurement.end({
|
|
13868
|
-
success: false,
|
|
13869
|
-
errorCode: error.errorCode,
|
|
13870
|
-
subErrorCode: error.subError,
|
|
13871
|
-
isNativeBroker: true,
|
|
13872
|
-
});
|
|
13873
|
-
throw error;
|
|
13874
|
-
});
|
|
13875
|
-
}
|
|
13876
|
-
catch (e) {
|
|
13877
|
-
if (e instanceof NativeAuthError) {
|
|
13878
|
-
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
|
|
13857
|
+
/**
|
|
13858
|
+
* KeyID must be present in the native request from when the PoP key was generated in order for
|
|
13859
|
+
* PopTokenGenerator to query the full key for signing
|
|
13860
|
+
*/
|
|
13861
|
+
if (!request.keyId) {
|
|
13862
|
+
throw createClientAuthError(keyIdMissing);
|
|
13879
13863
|
}
|
|
13880
|
-
|
|
13864
|
+
return popTokenGenerator.signPopToken(response.access_token, request.keyId, shrParameters);
|
|
13865
|
+
}
|
|
13866
|
+
else {
|
|
13867
|
+
return response.access_token;
|
|
13881
13868
|
}
|
|
13882
13869
|
}
|
|
13883
13870
|
/**
|
|
13884
|
-
*
|
|
13871
|
+
* Generates authentication result
|
|
13872
|
+
* @param response
|
|
13885
13873
|
* @param request
|
|
13886
|
-
* @param
|
|
13887
|
-
* @
|
|
13874
|
+
* @param idTokenObj
|
|
13875
|
+
* @param accountEntity
|
|
13876
|
+
* @param authority
|
|
13877
|
+
* @param reqTimestamp
|
|
13878
|
+
* @returns
|
|
13888
13879
|
*/
|
|
13889
|
-
|
|
13890
|
-
|
|
13891
|
-
|
|
13880
|
+
async generateAuthenticationResult(response, request, idTokenClaims, accountEntity, authority, reqTimestamp) {
|
|
13881
|
+
// Add Native Broker fields to Telemetry
|
|
13882
|
+
const mats = this.addTelemetryFromNativeResponse(response.properties.MATS);
|
|
13883
|
+
// If scopes not returned in server response, use request scopes
|
|
13884
|
+
const responseScopes = this.generateScopes(request.scope, response.scope);
|
|
13885
|
+
const accountProperties = response.account.properties || {};
|
|
13886
|
+
const uid = accountProperties["UID"] ||
|
|
13887
|
+
idTokenClaims.oid ||
|
|
13888
|
+
idTokenClaims.sub ||
|
|
13889
|
+
Constants.EMPTY_STRING;
|
|
13890
|
+
const tid = accountProperties["TenantId"] ||
|
|
13891
|
+
idTokenClaims.tid ||
|
|
13892
|
+
Constants.EMPTY_STRING;
|
|
13893
|
+
const accountInfo = updateAccountTenantProfileData(accountEntity.getAccountInfo(), undefined, // tenantProfile optional
|
|
13894
|
+
idTokenClaims, response.id_token);
|
|
13895
|
+
/**
|
|
13896
|
+
* In pairwise broker flows, this check prevents the broker's native account id
|
|
13897
|
+
* from being returned over the embedded app's account id.
|
|
13898
|
+
*/
|
|
13899
|
+
if (accountInfo.nativeAccountId !== response.account.id) {
|
|
13900
|
+
accountInfo.nativeAccountId = response.account.id;
|
|
13901
|
+
}
|
|
13902
|
+
// generate PoP token as needed
|
|
13903
|
+
const responseAccessToken = await this.generatePopAccessToken(response, request);
|
|
13904
|
+
const tokenType = request.tokenType === AuthenticationScheme.POP
|
|
13905
|
+
? AuthenticationScheme.POP
|
|
13906
|
+
: AuthenticationScheme.BEARER;
|
|
13907
|
+
const result = {
|
|
13908
|
+
authority: authority,
|
|
13909
|
+
uniqueId: uid,
|
|
13910
|
+
tenantId: tid,
|
|
13911
|
+
scopes: responseScopes.asArray(),
|
|
13912
|
+
account: accountInfo,
|
|
13913
|
+
idToken: response.id_token,
|
|
13914
|
+
idTokenClaims: idTokenClaims,
|
|
13915
|
+
accessToken: responseAccessToken,
|
|
13916
|
+
fromCache: mats ? this.isResponseFromCache(mats) : false,
|
|
13917
|
+
// Request timestamp and NativeResponse expires_in are in seconds, converting to Date for AuthenticationResult
|
|
13918
|
+
expiresOn: toDateFromSeconds(reqTimestamp + response.expires_in),
|
|
13919
|
+
tokenType: tokenType,
|
|
13892
13920
|
correlationId: this.correlationId,
|
|
13893
|
-
|
|
13894
|
-
|
|
13895
|
-
forceRefresh: false,
|
|
13921
|
+
state: response.state,
|
|
13922
|
+
fromNativeBroker: true,
|
|
13896
13923
|
};
|
|
13924
|
+
return result;
|
|
13897
13925
|
}
|
|
13898
13926
|
/**
|
|
13899
|
-
*
|
|
13900
|
-
* @param
|
|
13901
|
-
* @param request
|
|
13902
|
-
* @returns authenticationResult
|
|
13927
|
+
* cache the account entity in browser storage
|
|
13928
|
+
* @param accountEntity
|
|
13903
13929
|
*/
|
|
13904
|
-
async
|
|
13905
|
-
|
|
13906
|
-
|
|
13907
|
-
|
|
13908
|
-
|
|
13909
|
-
|
|
13910
|
-
const account = this.browserStorage.getBaseAccountInfo({
|
|
13911
|
-
nativeAccountId,
|
|
13930
|
+
async cacheAccount(accountEntity) {
|
|
13931
|
+
// Store the account info and hence `nativeAccountId` in browser cache
|
|
13932
|
+
await this.browserStorage.setAccount(accountEntity, this.correlationId);
|
|
13933
|
+
// Remove any existing cached tokens for this account in browser storage
|
|
13934
|
+
this.browserStorage.removeAccountContext(accountEntity).catch((e) => {
|
|
13935
|
+
this.logger.error(`Error occurred while removing account context from browser storage. ${e}`);
|
|
13912
13936
|
});
|
|
13913
|
-
if (!account) {
|
|
13914
|
-
throw createClientAuthError(noAccountFound);
|
|
13915
|
-
}
|
|
13916
|
-
// leverage silent flow for cached tokens retrieval
|
|
13917
|
-
try {
|
|
13918
|
-
const silentRequest = this.createSilentCacheRequest(request, account);
|
|
13919
|
-
const result = await this.silentCacheClient.acquireToken(silentRequest);
|
|
13920
|
-
const fullAccount = {
|
|
13921
|
-
...account,
|
|
13922
|
-
idTokenClaims: result?.idTokenClaims,
|
|
13923
|
-
idToken: result?.idToken,
|
|
13924
|
-
};
|
|
13925
|
-
return {
|
|
13926
|
-
...result,
|
|
13927
|
-
account: fullAccount,
|
|
13928
|
-
};
|
|
13929
|
-
}
|
|
13930
|
-
catch (e) {
|
|
13931
|
-
throw e;
|
|
13932
|
-
}
|
|
13933
13937
|
}
|
|
13934
13938
|
/**
|
|
13935
|
-
*
|
|
13936
|
-
* @param
|
|
13937
|
-
* @param
|
|
13939
|
+
* Stores the access_token and id_token in inmemory storage
|
|
13940
|
+
* @param response
|
|
13941
|
+
* @param request
|
|
13942
|
+
* @param homeAccountIdentifier
|
|
13943
|
+
* @param idTokenObj
|
|
13944
|
+
* @param responseAccessToken
|
|
13945
|
+
* @param tenantId
|
|
13946
|
+
* @param reqTimestamp
|
|
13938
13947
|
*/
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
|
|
13948
|
+
cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, responseAccessToken, tenantId, reqTimestamp) {
|
|
13949
|
+
const cachedIdToken = createIdTokenEntity(homeAccountIdentifier, request.authority, response.id_token || "", request.clientId, idTokenClaims.tid || "");
|
|
13950
|
+
// cache accessToken in inmemory storage
|
|
13951
|
+
const expiresIn = request.tokenType === AuthenticationScheme.POP
|
|
13952
|
+
? Constants.SHR_NONCE_VALIDITY
|
|
13953
|
+
: (typeof response.expires_in === "string"
|
|
13954
|
+
? parseInt(response.expires_in, 10)
|
|
13955
|
+
: response.expires_in) || 0;
|
|
13956
|
+
const tokenExpirationSeconds = reqTimestamp + expiresIn;
|
|
13957
|
+
const responseScopes = this.generateScopes(response.scope, request.scope);
|
|
13958
|
+
const cachedAccessToken = createAccessTokenEntity(homeAccountIdentifier, request.authority, responseAccessToken, request.clientId, idTokenClaims.tid || tenantId, responseScopes.printScopes(), tokenExpirationSeconds, 0, base64Decode, undefined, request.tokenType, undefined, request.keyId);
|
|
13959
|
+
const nativeCacheRecord = {
|
|
13960
|
+
idToken: cachedIdToken,
|
|
13961
|
+
accessToken: cachedAccessToken,
|
|
13947
13962
|
};
|
|
13948
|
-
|
|
13949
|
-
|
|
13950
|
-
|
|
13963
|
+
return this.nativeStorageManager.saveCacheRecord(nativeCacheRecord, this.correlationId, request.storeInCache);
|
|
13964
|
+
}
|
|
13965
|
+
getExpiresInValue(tokenType, expiresIn) {
|
|
13966
|
+
return tokenType === AuthenticationScheme.POP
|
|
13967
|
+
? Constants.SHR_NONCE_VALIDITY
|
|
13968
|
+
: (typeof expiresIn === "string"
|
|
13969
|
+
? parseInt(expiresIn, 10)
|
|
13970
|
+
: expiresIn) || 0;
|
|
13971
|
+
}
|
|
13972
|
+
addTelemetryFromNativeResponse(matsResponse) {
|
|
13973
|
+
const mats = this.getMATSFromResponse(matsResponse);
|
|
13974
|
+
if (!mats) {
|
|
13975
|
+
return null;
|
|
13951
13976
|
}
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
: this.getRedirectUri(request.redirectUri);
|
|
13971
|
-
rootMeasurement.end({ success: true });
|
|
13972
|
-
await this.navigationClient.navigateExternal(redirectUri, navigationOptions); // Need to treat this as external to ensure handleRedirectPromise is run again
|
|
13973
|
-
}
|
|
13974
|
-
/**
|
|
13975
|
-
* If the previous page called native platform for a token using redirect APIs, send the same request again and return the response
|
|
13976
|
-
* @param performanceClient {IPerformanceClient?}
|
|
13977
|
-
* @param correlationId {string?} correlation identifier
|
|
13978
|
-
*/
|
|
13979
|
-
async handleRedirectPromise(performanceClient, correlationId) {
|
|
13980
|
-
this.logger.trace("NativeInteractionClient - handleRedirectPromise called.");
|
|
13981
|
-
if (!this.browserStorage.isInteractionInProgress(true)) {
|
|
13982
|
-
this.logger.info("handleRedirectPromise called but there is no interaction in progress, returning null.");
|
|
13983
|
-
return null;
|
|
13984
|
-
}
|
|
13985
|
-
// remove prompt from the request to prevent WAM from prompting twice
|
|
13986
|
-
const cachedRequest = this.browserStorage.getCachedNativeRequest();
|
|
13987
|
-
if (!cachedRequest) {
|
|
13988
|
-
this.logger.verbose("NativeInteractionClient - handleRedirectPromise called but there is no cached request, returning null.");
|
|
13989
|
-
if (performanceClient && correlationId) {
|
|
13990
|
-
performanceClient?.addFields({ errorCode: "no_cached_request" }, correlationId);
|
|
13991
|
-
}
|
|
13992
|
-
return null;
|
|
13993
|
-
}
|
|
13994
|
-
const { prompt, ...request } = cachedRequest;
|
|
13995
|
-
if (prompt) {
|
|
13996
|
-
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.");
|
|
13997
|
-
}
|
|
13998
|
-
this.browserStorage.removeItem(this.browserStorage.generateCacheKey(TemporaryCacheKeys.NATIVE_REQUEST));
|
|
13999
|
-
const messageBody = {
|
|
14000
|
-
method: NativeExtensionMethod.GetToken,
|
|
14001
|
-
request: request,
|
|
14002
|
-
};
|
|
14003
|
-
const reqTimestamp = nowSeconds();
|
|
14004
|
-
try {
|
|
14005
|
-
this.logger.verbose("NativeInteractionClient - handleRedirectPromise sending message to native broker.");
|
|
14006
|
-
const response = await this.nativeMessageHandler.sendMessage(messageBody);
|
|
14007
|
-
this.validateNativeResponse(response);
|
|
14008
|
-
const result = this.handleNativeResponse(response, request, reqTimestamp);
|
|
14009
|
-
const res = await result;
|
|
14010
|
-
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
14011
|
-
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
14012
|
-
return res;
|
|
14013
|
-
}
|
|
14014
|
-
catch (e) {
|
|
14015
|
-
throw e;
|
|
14016
|
-
}
|
|
14017
|
-
}
|
|
14018
|
-
/**
|
|
14019
|
-
* Logout from native platform via browser extension
|
|
14020
|
-
* @param request
|
|
14021
|
-
*/
|
|
14022
|
-
logout() {
|
|
14023
|
-
this.logger.trace("NativeInteractionClient - logout called.");
|
|
14024
|
-
return Promise.reject("Logout not implemented yet");
|
|
14025
|
-
}
|
|
14026
|
-
/**
|
|
14027
|
-
* Transform response from native platform into AuthenticationResult object which will be returned to the end user
|
|
14028
|
-
* @param response
|
|
14029
|
-
* @param request
|
|
14030
|
-
* @param reqTimestamp
|
|
14031
|
-
*/
|
|
14032
|
-
async handleNativeResponse(response, request, reqTimestamp) {
|
|
14033
|
-
this.logger.trace("NativeInteractionClient - handleNativeResponse called.");
|
|
14034
|
-
// generate identifiers
|
|
14035
|
-
const idTokenClaims = extractTokenClaims(response.id_token, base64Decode);
|
|
14036
|
-
const homeAccountIdentifier = this.createHomeAccountIdentifier(response, idTokenClaims);
|
|
14037
|
-
const cachedhomeAccountId = this.browserStorage.getAccountInfoFilteredBy({
|
|
14038
|
-
nativeAccountId: request.accountId,
|
|
14039
|
-
})?.homeAccountId;
|
|
14040
|
-
// add exception for double brokering, please note this is temporary and will be fortified in future
|
|
14041
|
-
if (request.extraParameters?.child_client_id &&
|
|
14042
|
-
response.account.id !== request.accountId) {
|
|
14043
|
-
this.logger.info("handleNativeServerResponse: Double broker flow detected, ignoring accountId mismatch");
|
|
14044
|
-
}
|
|
14045
|
-
else if (homeAccountIdentifier !== cachedhomeAccountId &&
|
|
14046
|
-
response.account.id !== request.accountId) {
|
|
14047
|
-
// 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
|
|
14048
|
-
throw createNativeAuthError(userSwitch);
|
|
14049
|
-
}
|
|
14050
|
-
// Get the preferred_cache domain for the given authority
|
|
14051
|
-
const authority = await this.getDiscoveredAuthority({
|
|
14052
|
-
requestAuthority: request.authority,
|
|
14053
|
-
});
|
|
14054
|
-
const baseAccount = buildAccountToCache(this.browserStorage, authority, homeAccountIdentifier, base64Decode, idTokenClaims, response.client_info, undefined, // environment
|
|
14055
|
-
idTokenClaims.tid, undefined, // auth code payload
|
|
14056
|
-
response.account.id, this.logger);
|
|
14057
|
-
// Ensure expires_in is in number format
|
|
14058
|
-
response.expires_in = Number(response.expires_in);
|
|
14059
|
-
// generate authenticationResult
|
|
14060
|
-
const result = await this.generateAuthenticationResult(response, request, idTokenClaims, baseAccount, authority.canonicalAuthority, reqTimestamp);
|
|
14061
|
-
// cache accounts and tokens in the appropriate storage
|
|
14062
|
-
await this.cacheAccount(baseAccount);
|
|
14063
|
-
await this.cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, response.access_token, result.tenantId, reqTimestamp);
|
|
14064
|
-
return result;
|
|
13977
|
+
this.performanceClient.addFields({
|
|
13978
|
+
extensionId: this.platformAuthProvider.getExtensionId(),
|
|
13979
|
+
extensionVersion: this.platformAuthProvider.getExtensionVersion(),
|
|
13980
|
+
matsBrokerVersion: mats.broker_version,
|
|
13981
|
+
matsAccountJoinOnStart: mats.account_join_on_start,
|
|
13982
|
+
matsAccountJoinOnEnd: mats.account_join_on_end,
|
|
13983
|
+
matsDeviceJoin: mats.device_join,
|
|
13984
|
+
matsPromptBehavior: mats.prompt_behavior,
|
|
13985
|
+
matsApiErrorCode: mats.api_error_code,
|
|
13986
|
+
matsUiVisible: mats.ui_visible,
|
|
13987
|
+
matsSilentCode: mats.silent_code,
|
|
13988
|
+
matsSilentBiSubCode: mats.silent_bi_sub_code,
|
|
13989
|
+
matsSilentMessage: mats.silent_message,
|
|
13990
|
+
matsSilentStatus: mats.silent_status,
|
|
13991
|
+
matsHttpStatus: mats.http_status,
|
|
13992
|
+
matsHttpEventCount: mats.http_event_count,
|
|
13993
|
+
}, this.correlationId);
|
|
13994
|
+
return mats;
|
|
14065
13995
|
}
|
|
14066
13996
|
/**
|
|
14067
|
-
*
|
|
13997
|
+
* Gets MATS telemetry from native response
|
|
14068
13998
|
* @param response
|
|
14069
|
-
* @param idTokenObj
|
|
14070
13999
|
* @returns
|
|
14071
14000
|
*/
|
|
14072
|
-
|
|
14073
|
-
|
|
14074
|
-
|
|
14075
|
-
|
|
14001
|
+
getMATSFromResponse(matsResponse) {
|
|
14002
|
+
if (matsResponse) {
|
|
14003
|
+
try {
|
|
14004
|
+
return JSON.parse(matsResponse);
|
|
14005
|
+
}
|
|
14006
|
+
catch (e) {
|
|
14007
|
+
this.logger.error("NativeInteractionClient - Error parsing MATS telemetry, returning null instead");
|
|
14008
|
+
}
|
|
14009
|
+
}
|
|
14010
|
+
return null;
|
|
14076
14011
|
}
|
|
14077
14012
|
/**
|
|
14078
|
-
*
|
|
14013
|
+
* Returns whether or not response came from native cache
|
|
14079
14014
|
* @param response
|
|
14080
|
-
* @param request
|
|
14081
14015
|
* @returns
|
|
14082
14016
|
*/
|
|
14083
|
-
|
|
14084
|
-
|
|
14085
|
-
|
|
14086
|
-
|
|
14017
|
+
isResponseFromCache(mats) {
|
|
14018
|
+
if (typeof mats.is_cached === "undefined") {
|
|
14019
|
+
this.logger.verbose("NativeInteractionClient - MATS telemetry does not contain field indicating if response was served from cache. Returning false.");
|
|
14020
|
+
return false;
|
|
14021
|
+
}
|
|
14022
|
+
return !!mats.is_cached;
|
|
14087
14023
|
}
|
|
14088
14024
|
/**
|
|
14089
|
-
*
|
|
14025
|
+
* Translates developer provided request object into NativeRequest object
|
|
14090
14026
|
* @param request
|
|
14091
|
-
* @param response
|
|
14092
14027
|
*/
|
|
14093
|
-
async
|
|
14094
|
-
|
|
14095
|
-
|
|
14096
|
-
|
|
14097
|
-
|
|
14098
|
-
|
|
14099
|
-
|
|
14100
|
-
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14105
|
-
|
|
14106
|
-
|
|
14028
|
+
async initializeNativeRequest(request) {
|
|
14029
|
+
this.logger.trace("NativeInteractionClient - initializeNativeRequest called");
|
|
14030
|
+
const canonicalAuthority = await this.getCanonicalAuthority(request);
|
|
14031
|
+
// 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.
|
|
14032
|
+
const { scopes, ...remainingProperties } = request;
|
|
14033
|
+
const scopeSet = new ScopeSet(scopes || []);
|
|
14034
|
+
scopeSet.appendScopes(OIDC_DEFAULT_SCOPES);
|
|
14035
|
+
const validatedRequest = {
|
|
14036
|
+
...remainingProperties,
|
|
14037
|
+
accountId: this.accountId,
|
|
14038
|
+
clientId: this.config.auth.clientId,
|
|
14039
|
+
authority: canonicalAuthority.urlString,
|
|
14040
|
+
scope: scopeSet.printScopes(),
|
|
14041
|
+
redirectUri: this.getRedirectUri(request.redirectUri),
|
|
14042
|
+
prompt: this.getPrompt(request.prompt),
|
|
14043
|
+
correlationId: this.correlationId,
|
|
14044
|
+
tokenType: request.authenticationScheme,
|
|
14045
|
+
windowTitleSubstring: document.title,
|
|
14046
|
+
extraParameters: {
|
|
14047
|
+
...request.extraQueryParameters,
|
|
14048
|
+
...request.tokenQueryParameters,
|
|
14049
|
+
},
|
|
14050
|
+
extendedExpiryToken: false,
|
|
14051
|
+
keyId: request.popKid,
|
|
14052
|
+
};
|
|
14053
|
+
// Check for PoP token requests: signPopToken should only be set to true if popKid is not set
|
|
14054
|
+
if (validatedRequest.signPopToken && !!request.popKid) {
|
|
14055
|
+
throw createBrowserAuthError(invalidPopTokenRequest);
|
|
14056
|
+
}
|
|
14057
|
+
this.handleExtraBrokerParams(validatedRequest);
|
|
14058
|
+
validatedRequest.extraParameters =
|
|
14059
|
+
validatedRequest.extraParameters || {};
|
|
14060
|
+
validatedRequest.extraParameters.telemetry =
|
|
14061
|
+
PlatformAuthConstants.MATS_TELEMETRY;
|
|
14062
|
+
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14063
|
+
// add POP request type
|
|
14107
14064
|
const shrParameters = {
|
|
14108
|
-
resourceRequestMethod: request.resourceRequestMethod,
|
|
14109
14065
|
resourceRequestUri: request.resourceRequestUri,
|
|
14066
|
+
resourceRequestMethod: request.resourceRequestMethod,
|
|
14110
14067
|
shrClaims: request.shrClaims,
|
|
14111
14068
|
shrNonce: request.shrNonce,
|
|
14112
14069
|
};
|
|
14113
|
-
|
|
14114
|
-
|
|
14115
|
-
|
|
14116
|
-
|
|
14117
|
-
|
|
14118
|
-
|
|
14070
|
+
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto);
|
|
14071
|
+
// generate reqCnf if not provided in the request
|
|
14072
|
+
let reqCnfData;
|
|
14073
|
+
if (!validatedRequest.keyId) {
|
|
14074
|
+
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(shrParameters, this.logger);
|
|
14075
|
+
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14076
|
+
validatedRequest.keyId = generatedReqCnfData.kid;
|
|
14077
|
+
validatedRequest.signPopToken = true;
|
|
14119
14078
|
}
|
|
14120
|
-
|
|
14079
|
+
else {
|
|
14080
|
+
reqCnfData = this.browserCrypto.base64UrlEncode(JSON.stringify({ kid: validatedRequest.keyId }));
|
|
14081
|
+
validatedRequest.signPopToken = false;
|
|
14082
|
+
}
|
|
14083
|
+
// SPAs require whole string to be passed to broker
|
|
14084
|
+
validatedRequest.reqCnf = reqCnfData;
|
|
14121
14085
|
}
|
|
14122
|
-
|
|
14123
|
-
|
|
14086
|
+
this.addRequestSKUs(validatedRequest);
|
|
14087
|
+
return validatedRequest;
|
|
14088
|
+
}
|
|
14089
|
+
async getCanonicalAuthority(request) {
|
|
14090
|
+
const requestAuthority = request.authority || this.config.auth.authority;
|
|
14091
|
+
if (request.account) {
|
|
14092
|
+
// validate authority
|
|
14093
|
+
await this.getDiscoveredAuthority({
|
|
14094
|
+
requestAuthority,
|
|
14095
|
+
requestAzureCloudOptions: request.azureCloudOptions,
|
|
14096
|
+
account: request.account,
|
|
14097
|
+
});
|
|
14098
|
+
}
|
|
14099
|
+
const canonicalAuthority = new UrlString(requestAuthority);
|
|
14100
|
+
canonicalAuthority.validateAsUri();
|
|
14101
|
+
return canonicalAuthority;
|
|
14102
|
+
}
|
|
14103
|
+
getPrompt(prompt) {
|
|
14104
|
+
// If request is silent, prompt is always none
|
|
14105
|
+
switch (this.apiId) {
|
|
14106
|
+
case ApiId.ssoSilent:
|
|
14107
|
+
case ApiId.acquireTokenSilent_silentFlow:
|
|
14108
|
+
this.logger.trace("initializeNativeRequest: silent request sets prompt to none");
|
|
14109
|
+
return PromptValue.NONE;
|
|
14110
|
+
}
|
|
14111
|
+
// Prompt not provided, request may proceed and native broker decides if it needs to prompt
|
|
14112
|
+
if (!prompt) {
|
|
14113
|
+
this.logger.trace("initializeNativeRequest: prompt was not provided");
|
|
14114
|
+
return undefined;
|
|
14115
|
+
}
|
|
14116
|
+
// If request is interactive, check if prompt provided is allowed to go directly to native broker
|
|
14117
|
+
switch (prompt) {
|
|
14118
|
+
case PromptValue.NONE:
|
|
14119
|
+
case PromptValue.CONSENT:
|
|
14120
|
+
case PromptValue.LOGIN:
|
|
14121
|
+
this.logger.trace("initializeNativeRequest: prompt is compatible with native flow");
|
|
14122
|
+
return prompt;
|
|
14123
|
+
default:
|
|
14124
|
+
this.logger.trace(`initializeNativeRequest: prompt = ${prompt} is not compatible with native flow`);
|
|
14125
|
+
throw createBrowserAuthError(nativePromptNotSupported);
|
|
14124
14126
|
}
|
|
14125
14127
|
}
|
|
14126
14128
|
/**
|
|
14127
|
-
*
|
|
14128
|
-
* @param
|
|
14129
|
-
* @
|
|
14130
|
-
* @param idTokenObj
|
|
14131
|
-
* @param accountEntity
|
|
14132
|
-
* @param authority
|
|
14133
|
-
* @param reqTimestamp
|
|
14134
|
-
* @returns
|
|
14129
|
+
* Handles extra broker request parameters
|
|
14130
|
+
* @param request {PlatformAuthRequest}
|
|
14131
|
+
* @private
|
|
14135
14132
|
*/
|
|
14136
|
-
|
|
14137
|
-
|
|
14138
|
-
|
|
14139
|
-
|
|
14140
|
-
|
|
14141
|
-
|
|
14142
|
-
|
|
14143
|
-
const accountProperties = response.account.properties || {};
|
|
14144
|
-
const uid = accountProperties["UID"] ||
|
|
14145
|
-
idTokenClaims.oid ||
|
|
14146
|
-
idTokenClaims.sub ||
|
|
14147
|
-
Constants.EMPTY_STRING;
|
|
14148
|
-
const tid = accountProperties["TenantId"] ||
|
|
14149
|
-
idTokenClaims.tid ||
|
|
14150
|
-
Constants.EMPTY_STRING;
|
|
14151
|
-
const accountInfo = updateAccountTenantProfileData(accountEntity.getAccountInfo(), undefined, // tenantProfile optional
|
|
14152
|
-
idTokenClaims, response.id_token);
|
|
14153
|
-
/**
|
|
14154
|
-
* In pairwise broker flows, this check prevents the broker's native account id
|
|
14155
|
-
* from being returned over the embedded app's account id.
|
|
14156
|
-
*/
|
|
14157
|
-
if (accountInfo.nativeAccountId !== response.account.id) {
|
|
14158
|
-
accountInfo.nativeAccountId = response.account.id;
|
|
14133
|
+
handleExtraBrokerParams(request) {
|
|
14134
|
+
const hasExtraBrokerParams = request.extraParameters &&
|
|
14135
|
+
request.extraParameters.hasOwnProperty(BROKER_CLIENT_ID) &&
|
|
14136
|
+
request.extraParameters.hasOwnProperty(BROKER_REDIRECT_URI) &&
|
|
14137
|
+
request.extraParameters.hasOwnProperty(CLIENT_ID);
|
|
14138
|
+
if (!request.embeddedClientId && !hasExtraBrokerParams) {
|
|
14139
|
+
return;
|
|
14159
14140
|
}
|
|
14160
|
-
|
|
14161
|
-
const
|
|
14162
|
-
|
|
14163
|
-
|
|
14164
|
-
|
|
14165
|
-
|
|
14166
|
-
|
|
14167
|
-
|
|
14168
|
-
|
|
14169
|
-
|
|
14170
|
-
|
|
14171
|
-
|
|
14172
|
-
|
|
14173
|
-
|
|
14174
|
-
|
|
14175
|
-
// Request timestamp and NativeResponse expires_in are in seconds, converting to Date for AuthenticationResult
|
|
14176
|
-
expiresOn: toDateFromSeconds(reqTimestamp + response.expires_in),
|
|
14177
|
-
tokenType: tokenType,
|
|
14178
|
-
correlationId: this.correlationId,
|
|
14179
|
-
state: response.state,
|
|
14180
|
-
fromNativeBroker: true,
|
|
14141
|
+
let child_client_id = "";
|
|
14142
|
+
const child_redirect_uri = request.redirectUri;
|
|
14143
|
+
if (request.embeddedClientId) {
|
|
14144
|
+
request.redirectUri = this.config.auth.redirectUri;
|
|
14145
|
+
child_client_id = request.embeddedClientId;
|
|
14146
|
+
}
|
|
14147
|
+
else if (request.extraParameters) {
|
|
14148
|
+
request.redirectUri =
|
|
14149
|
+
request.extraParameters[BROKER_REDIRECT_URI];
|
|
14150
|
+
child_client_id =
|
|
14151
|
+
request.extraParameters[CLIENT_ID];
|
|
14152
|
+
}
|
|
14153
|
+
request.extraParameters = {
|
|
14154
|
+
child_client_id,
|
|
14155
|
+
child_redirect_uri,
|
|
14181
14156
|
};
|
|
14182
|
-
|
|
14157
|
+
this.performanceClient?.addFields({
|
|
14158
|
+
embeddedClientId: child_client_id,
|
|
14159
|
+
embeddedRedirectUri: child_redirect_uri,
|
|
14160
|
+
}, request.correlationId);
|
|
14161
|
+
}
|
|
14162
|
+
}
|
|
14163
|
+
|
|
14164
|
+
/*
|
|
14165
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14166
|
+
* Licensed under the MIT License.
|
|
14167
|
+
*/
|
|
14168
|
+
/**
|
|
14169
|
+
* Returns map of parameters that are applicable to all calls to /authorize whether using PKCE or EAR
|
|
14170
|
+
* @param config
|
|
14171
|
+
* @param authority
|
|
14172
|
+
* @param request
|
|
14173
|
+
* @param logger
|
|
14174
|
+
* @param performanceClient
|
|
14175
|
+
* @returns
|
|
14176
|
+
*/
|
|
14177
|
+
async function getStandardParameters(config, authority, request, logger, performanceClient) {
|
|
14178
|
+
const parameters = getStandardAuthorizeRequestParameters({ ...config.auth, authority: authority }, request, logger, performanceClient);
|
|
14179
|
+
addLibraryInfo(parameters, {
|
|
14180
|
+
sku: BrowserConstants.MSAL_SKU,
|
|
14181
|
+
version: version,
|
|
14182
|
+
os: "",
|
|
14183
|
+
cpu: "",
|
|
14184
|
+
});
|
|
14185
|
+
if (config.auth.protocolMode !== ProtocolMode.OIDC) {
|
|
14186
|
+
addApplicationTelemetry(parameters, config.telemetry.application);
|
|
14187
|
+
}
|
|
14188
|
+
if (request.platformBroker) {
|
|
14189
|
+
// signal ests that this is a WAM call
|
|
14190
|
+
addNativeBroker(parameters);
|
|
14191
|
+
// pass the req_cnf for POP
|
|
14192
|
+
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14193
|
+
const cryptoOps = new CryptoOps(logger, performanceClient);
|
|
14194
|
+
const popTokenGenerator = new PopTokenGenerator(cryptoOps);
|
|
14195
|
+
// req_cnf is always sent as a string for SPAs
|
|
14196
|
+
let reqCnfData;
|
|
14197
|
+
if (!request.popKid) {
|
|
14198
|
+
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, logger, performanceClient, request.correlationId)(request, logger);
|
|
14199
|
+
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14200
|
+
}
|
|
14201
|
+
else {
|
|
14202
|
+
reqCnfData = cryptoOps.encodeKid(request.popKid);
|
|
14203
|
+
}
|
|
14204
|
+
addPopToken(parameters, reqCnfData);
|
|
14205
|
+
}
|
|
14206
|
+
}
|
|
14207
|
+
instrumentBrokerParams(parameters, request.correlationId, performanceClient);
|
|
14208
|
+
return parameters;
|
|
14209
|
+
}
|
|
14210
|
+
/**
|
|
14211
|
+
* Gets the full /authorize URL with request parameters when using Auth Code + PKCE
|
|
14212
|
+
* @param config
|
|
14213
|
+
* @param authority
|
|
14214
|
+
* @param request
|
|
14215
|
+
* @param logger
|
|
14216
|
+
* @param performanceClient
|
|
14217
|
+
* @returns
|
|
14218
|
+
*/
|
|
14219
|
+
async function getAuthCodeRequestUrl(config, authority, request, logger, performanceClient) {
|
|
14220
|
+
if (!request.codeChallenge) {
|
|
14221
|
+
throw createClientConfigurationError(pkceParamsMissing);
|
|
14222
|
+
}
|
|
14223
|
+
const parameters = await invokeAsync(getStandardParameters, PerformanceEvents.GetStandardParams, logger, performanceClient, request.correlationId)(config, authority, request, logger, performanceClient);
|
|
14224
|
+
addResponseType(parameters, OAuthResponseType.CODE);
|
|
14225
|
+
addCodeChallengeParams(parameters, request.codeChallenge, Constants.S256_CODE_CHALLENGE_METHOD);
|
|
14226
|
+
addExtraQueryParameters(parameters, request.extraQueryParameters || {});
|
|
14227
|
+
return getAuthorizeUrl(authority, parameters, config.auth.encodeExtraQueryParams, request.extraQueryParameters);
|
|
14228
|
+
}
|
|
14229
|
+
/**
|
|
14230
|
+
* Gets the form that will be posted to /authorize with request parameters when using EAR
|
|
14231
|
+
*/
|
|
14232
|
+
async function getEARForm(frame, config, authority, request, logger, performanceClient) {
|
|
14233
|
+
if (!request.earJwk) {
|
|
14234
|
+
throw createBrowserAuthError(earJwkEmpty);
|
|
14235
|
+
}
|
|
14236
|
+
const parameters = await getStandardParameters(config, authority, request, logger, performanceClient);
|
|
14237
|
+
addResponseType(parameters, OAuthResponseType.IDTOKEN_TOKEN_REFRESHTOKEN);
|
|
14238
|
+
addEARParameters(parameters, request.earJwk);
|
|
14239
|
+
const queryParams = new Map();
|
|
14240
|
+
addExtraQueryParameters(queryParams, request.extraQueryParameters || {});
|
|
14241
|
+
const url = getAuthorizeUrl(authority, queryParams, config.auth.encodeExtraQueryParams, request.extraQueryParameters);
|
|
14242
|
+
return createForm(frame, url, parameters);
|
|
14243
|
+
}
|
|
14244
|
+
/**
|
|
14245
|
+
* Creates form element in the provided document with auth parameters in the post body
|
|
14246
|
+
* @param frame
|
|
14247
|
+
* @param authorizeUrl
|
|
14248
|
+
* @param parameters
|
|
14249
|
+
* @returns
|
|
14250
|
+
*/
|
|
14251
|
+
function createForm(frame, authorizeUrl, parameters) {
|
|
14252
|
+
const form = frame.createElement("form");
|
|
14253
|
+
form.method = "post";
|
|
14254
|
+
form.action = authorizeUrl;
|
|
14255
|
+
parameters.forEach((value, key) => {
|
|
14256
|
+
const param = frame.createElement("input");
|
|
14257
|
+
param.hidden = true;
|
|
14258
|
+
param.name = key;
|
|
14259
|
+
param.value = value;
|
|
14260
|
+
form.appendChild(param);
|
|
14261
|
+
});
|
|
14262
|
+
frame.body.appendChild(form);
|
|
14263
|
+
return form;
|
|
14264
|
+
}
|
|
14265
|
+
/**
|
|
14266
|
+
* Response handler when server returns accountId on the /authorize request
|
|
14267
|
+
* @param request
|
|
14268
|
+
* @param accountId
|
|
14269
|
+
* @param apiId
|
|
14270
|
+
* @param config
|
|
14271
|
+
* @param browserStorage
|
|
14272
|
+
* @param nativeStorage
|
|
14273
|
+
* @param eventHandler
|
|
14274
|
+
* @param logger
|
|
14275
|
+
* @param performanceClient
|
|
14276
|
+
* @param nativeMessageHandler
|
|
14277
|
+
* @returns
|
|
14278
|
+
*/
|
|
14279
|
+
async function handleResponsePlatformBroker(request, accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider) {
|
|
14280
|
+
logger.verbose("Account id found, calling WAM for token");
|
|
14281
|
+
if (!platformAuthProvider) {
|
|
14282
|
+
throw createBrowserAuthError(nativeConnectionNotEstablished);
|
|
14283
|
+
}
|
|
14284
|
+
const browserCrypto = new CryptoOps(logger, performanceClient);
|
|
14285
|
+
const nativeInteractionClient = new PlatformAuthInteractionClient(config, browserStorage, browserCrypto, logger, eventHandler, config.system.navigationClient, apiId, performanceClient, platformAuthProvider, accountId, nativeStorage, request.correlationId);
|
|
14286
|
+
const { userRequestState } = ProtocolUtils.parseRequestState(browserCrypto, request.state);
|
|
14287
|
+
return invokeAsync(nativeInteractionClient.acquireToken.bind(nativeInteractionClient), PerformanceEvents.NativeInteractionClientAcquireToken, logger, performanceClient, request.correlationId)({
|
|
14288
|
+
...request,
|
|
14289
|
+
state: userRequestState,
|
|
14290
|
+
prompt: undefined, // Server should handle the prompt, ideally native broker can do this part silently
|
|
14291
|
+
});
|
|
14292
|
+
}
|
|
14293
|
+
/**
|
|
14294
|
+
* Response handler when server returns code on the /authorize request
|
|
14295
|
+
* @param request
|
|
14296
|
+
* @param response
|
|
14297
|
+
* @param codeVerifier
|
|
14298
|
+
* @param authClient
|
|
14299
|
+
* @param browserStorage
|
|
14300
|
+
* @param logger
|
|
14301
|
+
* @param performanceClient
|
|
14302
|
+
* @returns
|
|
14303
|
+
*/
|
|
14304
|
+
async function handleResponseCode(request, response, codeVerifier, apiId, config, authClient, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider) {
|
|
14305
|
+
// Remove throttle if it exists
|
|
14306
|
+
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14307
|
+
if (response.accountId) {
|
|
14308
|
+
return invokeAsync(handleResponsePlatformBroker, PerformanceEvents.HandleResponsePlatformBroker, logger, performanceClient, request.correlationId)(request, response.accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider);
|
|
14309
|
+
}
|
|
14310
|
+
const authCodeRequest = {
|
|
14311
|
+
...request,
|
|
14312
|
+
code: response.code || "",
|
|
14313
|
+
codeVerifier: codeVerifier,
|
|
14314
|
+
};
|
|
14315
|
+
// Create popup interaction handler.
|
|
14316
|
+
const interactionHandler = new InteractionHandler(authClient, browserStorage, authCodeRequest, logger, performanceClient);
|
|
14317
|
+
// Handle response from hash string.
|
|
14318
|
+
const result = await invokeAsync(interactionHandler.handleCodeResponse.bind(interactionHandler), PerformanceEvents.HandleCodeResponse, logger, performanceClient, request.correlationId)(response, request);
|
|
14319
|
+
return result;
|
|
14320
|
+
}
|
|
14321
|
+
/**
|
|
14322
|
+
* Response handler when server returns ear_jwe on the /authorize request
|
|
14323
|
+
* @param request
|
|
14324
|
+
* @param response
|
|
14325
|
+
* @param apiId
|
|
14326
|
+
* @param config
|
|
14327
|
+
* @param authority
|
|
14328
|
+
* @param browserStorage
|
|
14329
|
+
* @param nativeStorage
|
|
14330
|
+
* @param eventHandler
|
|
14331
|
+
* @param logger
|
|
14332
|
+
* @param performanceClient
|
|
14333
|
+
* @param nativeMessageHandler
|
|
14334
|
+
* @returns
|
|
14335
|
+
*/
|
|
14336
|
+
async function handleResponseEAR(request, response, apiId, config, authority, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider) {
|
|
14337
|
+
// Remove throttle if it exists
|
|
14338
|
+
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14339
|
+
// Validate state & check response for errors
|
|
14340
|
+
validateAuthorizationResponse(response, request.state);
|
|
14341
|
+
if (!response.ear_jwe) {
|
|
14342
|
+
throw createBrowserAuthError(earJweEmpty);
|
|
14343
|
+
}
|
|
14344
|
+
if (!request.earJwk) {
|
|
14345
|
+
throw createBrowserAuthError(earJwkEmpty);
|
|
14346
|
+
}
|
|
14347
|
+
const decryptedData = JSON.parse(await invokeAsync(decryptEarResponse, PerformanceEvents.DecryptEarResponse, logger, performanceClient, request.correlationId)(request.earJwk, response.ear_jwe));
|
|
14348
|
+
if (decryptedData.accountId) {
|
|
14349
|
+
return invokeAsync(handleResponsePlatformBroker, PerformanceEvents.HandleResponsePlatformBroker, logger, performanceClient, request.correlationId)(request, decryptedData.accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, platformAuthProvider);
|
|
14350
|
+
}
|
|
14351
|
+
const responseHandler = new ResponseHandler(config.auth.clientId, browserStorage, new CryptoOps(logger, performanceClient), logger, null, null, performanceClient);
|
|
14352
|
+
// Validate response. This function throws a server error if an error is returned by the server.
|
|
14353
|
+
responseHandler.validateTokenResponse(decryptedData);
|
|
14354
|
+
// Temporary until response handler is refactored to be more flow agnostic.
|
|
14355
|
+
const additionalData = {
|
|
14356
|
+
code: "",
|
|
14357
|
+
state: request.state,
|
|
14358
|
+
nonce: request.nonce,
|
|
14359
|
+
client_info: decryptedData.client_info,
|
|
14360
|
+
cloud_graph_host_name: decryptedData.cloud_graph_host_name,
|
|
14361
|
+
cloud_instance_host_name: decryptedData.cloud_instance_host_name,
|
|
14362
|
+
cloud_instance_name: decryptedData.cloud_instance_name,
|
|
14363
|
+
msgraph_host: decryptedData.msgraph_host,
|
|
14364
|
+
};
|
|
14365
|
+
return (await invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), PerformanceEvents.HandleServerTokenResponse, logger, performanceClient, request.correlationId)(decryptedData, authority, nowSeconds(), request, additionalData, undefined, undefined, undefined, undefined));
|
|
14366
|
+
}
|
|
14367
|
+
|
|
14368
|
+
/*
|
|
14369
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14370
|
+
* Licensed under the MIT License.
|
|
14371
|
+
*/
|
|
14372
|
+
// Constant byte array length
|
|
14373
|
+
const RANDOM_BYTE_ARR_LENGTH = 32;
|
|
14374
|
+
/**
|
|
14375
|
+
* This file defines APIs to generate PKCE codes and code verifiers.
|
|
14376
|
+
*/
|
|
14377
|
+
/**
|
|
14378
|
+
* Generates PKCE Codes. See the RFC for more information: https://tools.ietf.org/html/rfc7636
|
|
14379
|
+
*/
|
|
14380
|
+
async function generatePkceCodes(performanceClient, logger, correlationId) {
|
|
14381
|
+
performanceClient.addQueueMeasurement(PerformanceEvents.GeneratePkceCodes, correlationId);
|
|
14382
|
+
const codeVerifier = invoke(generateCodeVerifier, PerformanceEvents.GenerateCodeVerifier, logger, performanceClient, correlationId)(performanceClient, logger, correlationId);
|
|
14383
|
+
const codeChallenge = await invokeAsync(generateCodeChallengeFromVerifier, PerformanceEvents.GenerateCodeChallengeFromVerifier, logger, performanceClient, correlationId)(codeVerifier, performanceClient, logger, correlationId);
|
|
14384
|
+
return {
|
|
14385
|
+
verifier: codeVerifier,
|
|
14386
|
+
challenge: codeChallenge,
|
|
14387
|
+
};
|
|
14388
|
+
}
|
|
14389
|
+
/**
|
|
14390
|
+
* Generates a random 32 byte buffer and returns the base64
|
|
14391
|
+
* encoded string to be used as a PKCE Code Verifier
|
|
14392
|
+
*/
|
|
14393
|
+
function generateCodeVerifier(performanceClient, logger, correlationId) {
|
|
14394
|
+
try {
|
|
14395
|
+
// Generate random values as utf-8
|
|
14396
|
+
const buffer = new Uint8Array(RANDOM_BYTE_ARR_LENGTH);
|
|
14397
|
+
invoke(getRandomValues, PerformanceEvents.GetRandomValues, logger, performanceClient, correlationId)(buffer);
|
|
14398
|
+
// encode verifier as base64
|
|
14399
|
+
const pkceCodeVerifierB64 = urlEncodeArr(buffer);
|
|
14400
|
+
return pkceCodeVerifierB64;
|
|
14401
|
+
}
|
|
14402
|
+
catch (e) {
|
|
14403
|
+
throw createBrowserAuthError(pkceNotCreated);
|
|
14404
|
+
}
|
|
14405
|
+
}
|
|
14406
|
+
/**
|
|
14407
|
+
* Creates a base64 encoded PKCE Code Challenge string from the
|
|
14408
|
+
* hash created from the PKCE Code Verifier supplied
|
|
14409
|
+
*/
|
|
14410
|
+
async function generateCodeChallengeFromVerifier(pkceCodeVerifier, performanceClient, logger, correlationId) {
|
|
14411
|
+
performanceClient.addQueueMeasurement(PerformanceEvents.GenerateCodeChallengeFromVerifier, correlationId);
|
|
14412
|
+
try {
|
|
14413
|
+
// hashed verifier
|
|
14414
|
+
const pkceHashedCodeVerifier = await invokeAsync(sha256Digest, PerformanceEvents.Sha256Digest, logger, performanceClient, correlationId)(pkceCodeVerifier, performanceClient, correlationId);
|
|
14415
|
+
// encode hash as base64
|
|
14416
|
+
return urlEncodeArr(new Uint8Array(pkceHashedCodeVerifier));
|
|
14417
|
+
}
|
|
14418
|
+
catch (e) {
|
|
14419
|
+
throw createBrowserAuthError(pkceNotCreated);
|
|
14420
|
+
}
|
|
14421
|
+
}
|
|
14422
|
+
|
|
14423
|
+
/*
|
|
14424
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14425
|
+
* Licensed under the MIT License.
|
|
14426
|
+
*/
|
|
14427
|
+
class PlatformAuthExtensionHandler {
|
|
14428
|
+
constructor(logger, handshakeTimeoutMs, performanceClient, extensionId) {
|
|
14429
|
+
this.logger = logger;
|
|
14430
|
+
this.handshakeTimeoutMs = handshakeTimeoutMs;
|
|
14431
|
+
this.extensionId = extensionId;
|
|
14432
|
+
this.resolvers = new Map(); // Used for non-handshake messages
|
|
14433
|
+
this.handshakeResolvers = new Map(); // Used for handshake messages
|
|
14434
|
+
this.messageChannel = new MessageChannel();
|
|
14435
|
+
this.windowListener = this.onWindowMessage.bind(this); // Window event callback doesn't have access to 'this' unless it's bound
|
|
14436
|
+
this.performanceClient = performanceClient;
|
|
14437
|
+
this.handshakeEvent = performanceClient.startMeasurement(PerformanceEvents.NativeMessageHandlerHandshake);
|
|
14438
|
+
this.platformAuthType =
|
|
14439
|
+
PlatformAuthConstants.PLATFORM_EXTENSION_PROVIDER;
|
|
14183
14440
|
}
|
|
14184
14441
|
/**
|
|
14185
|
-
*
|
|
14186
|
-
* @param
|
|
14442
|
+
* Sends a given message to the extension and resolves with the extension response
|
|
14443
|
+
* @param request
|
|
14187
14444
|
*/
|
|
14188
|
-
async
|
|
14189
|
-
|
|
14190
|
-
|
|
14191
|
-
|
|
14192
|
-
|
|
14193
|
-
|
|
14445
|
+
async sendMessage(request) {
|
|
14446
|
+
this.logger.trace(this.platformAuthType + " - sendMessage called.");
|
|
14447
|
+
// fall back to native calls
|
|
14448
|
+
const messageBody = {
|
|
14449
|
+
method: NativeExtensionMethod.GetToken,
|
|
14450
|
+
request: request,
|
|
14451
|
+
};
|
|
14452
|
+
const req = {
|
|
14453
|
+
channel: PlatformAuthConstants.CHANNEL_ID,
|
|
14454
|
+
extensionId: this.extensionId,
|
|
14455
|
+
responseId: createNewGuid(),
|
|
14456
|
+
body: messageBody,
|
|
14457
|
+
};
|
|
14458
|
+
this.logger.trace(this.platformAuthType + " - Sending request to browser extension");
|
|
14459
|
+
this.logger.tracePii(this.platformAuthType +
|
|
14460
|
+
` - Sending request to browser extension: ${JSON.stringify(req)}`);
|
|
14461
|
+
this.messageChannel.port1.postMessage(req);
|
|
14462
|
+
const response = await new Promise((resolve, reject) => {
|
|
14463
|
+
this.resolvers.set(req.responseId, { resolve, reject });
|
|
14194
14464
|
});
|
|
14465
|
+
const validatedResponse = this.validatePlatformBrokerResponse(response);
|
|
14466
|
+
return validatedResponse;
|
|
14195
14467
|
}
|
|
14196
14468
|
/**
|
|
14197
|
-
*
|
|
14198
|
-
* @param
|
|
14199
|
-
* @param
|
|
14200
|
-
* @param
|
|
14201
|
-
* @param
|
|
14202
|
-
* @param responseAccessToken
|
|
14203
|
-
* @param tenantId
|
|
14204
|
-
* @param reqTimestamp
|
|
14469
|
+
* Returns an instance of the MessageHandler that has successfully established a connection with an extension
|
|
14470
|
+
* @param {Logger} logger
|
|
14471
|
+
* @param {number} handshakeTimeoutMs
|
|
14472
|
+
* @param {IPerformanceClient} performanceClient
|
|
14473
|
+
* @param {ICrypto} crypto
|
|
14205
14474
|
*/
|
|
14206
|
-
|
|
14207
|
-
|
|
14208
|
-
|
|
14209
|
-
|
|
14210
|
-
|
|
14211
|
-
|
|
14212
|
-
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
|
|
14217
|
-
|
|
14218
|
-
|
|
14219
|
-
|
|
14475
|
+
static async createProvider(logger, handshakeTimeoutMs, performanceClient) {
|
|
14476
|
+
logger.trace("PlatformAuthExtensionHandler - createProvider called.");
|
|
14477
|
+
try {
|
|
14478
|
+
const preferredProvider = new PlatformAuthExtensionHandler(logger, handshakeTimeoutMs, performanceClient, PlatformAuthConstants.PREFERRED_EXTENSION_ID);
|
|
14479
|
+
await preferredProvider.sendHandshakeRequest();
|
|
14480
|
+
return preferredProvider;
|
|
14481
|
+
}
|
|
14482
|
+
catch (e) {
|
|
14483
|
+
// If preferred extension fails for whatever reason, fallback to using any installed extension
|
|
14484
|
+
const backupProvider = new PlatformAuthExtensionHandler(logger, handshakeTimeoutMs, performanceClient);
|
|
14485
|
+
await backupProvider.sendHandshakeRequest();
|
|
14486
|
+
return backupProvider;
|
|
14487
|
+
}
|
|
14488
|
+
}
|
|
14489
|
+
/**
|
|
14490
|
+
* Send handshake request helper.
|
|
14491
|
+
*/
|
|
14492
|
+
async sendHandshakeRequest() {
|
|
14493
|
+
this.logger.trace(this.platformAuthType + " - sendHandshakeRequest called.");
|
|
14494
|
+
// Register this event listener before sending handshake
|
|
14495
|
+
window.addEventListener("message", this.windowListener, false); // false is important, because content script message processing should work first
|
|
14496
|
+
const req = {
|
|
14497
|
+
channel: PlatformAuthConstants.CHANNEL_ID,
|
|
14498
|
+
extensionId: this.extensionId,
|
|
14499
|
+
responseId: createNewGuid(),
|
|
14500
|
+
body: {
|
|
14501
|
+
method: NativeExtensionMethod.HandshakeRequest,
|
|
14502
|
+
},
|
|
14220
14503
|
};
|
|
14221
|
-
|
|
14504
|
+
this.handshakeEvent.add({
|
|
14505
|
+
extensionId: this.extensionId,
|
|
14506
|
+
extensionHandshakeTimeoutMs: this.handshakeTimeoutMs,
|
|
14507
|
+
});
|
|
14508
|
+
this.messageChannel.port1.onmessage = (event) => {
|
|
14509
|
+
this.onChannelMessage(event);
|
|
14510
|
+
};
|
|
14511
|
+
window.postMessage(req, window.origin, [this.messageChannel.port2]);
|
|
14512
|
+
return new Promise((resolve, reject) => {
|
|
14513
|
+
this.handshakeResolvers.set(req.responseId, { resolve, reject });
|
|
14514
|
+
this.timeoutId = window.setTimeout(() => {
|
|
14515
|
+
/*
|
|
14516
|
+
* Throw an error if neither HandshakeResponse nor original Handshake request are received in a reasonable timeframe.
|
|
14517
|
+
* This typically suggests an event handler stopped propagation of the Handshake request but did not respond to it on the MessageChannel port
|
|
14518
|
+
*/
|
|
14519
|
+
window.removeEventListener("message", this.windowListener, false);
|
|
14520
|
+
this.messageChannel.port1.close();
|
|
14521
|
+
this.messageChannel.port2.close();
|
|
14522
|
+
this.handshakeEvent.end({
|
|
14523
|
+
extensionHandshakeTimedOut: true,
|
|
14524
|
+
success: false,
|
|
14525
|
+
});
|
|
14526
|
+
reject(createBrowserAuthError(nativeHandshakeTimeout));
|
|
14527
|
+
this.handshakeResolvers.delete(req.responseId);
|
|
14528
|
+
}, this.handshakeTimeoutMs); // Use a reasonable timeout in milliseconds here
|
|
14529
|
+
});
|
|
14222
14530
|
}
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14226
|
-
|
|
14531
|
+
/**
|
|
14532
|
+
* Invoked when a message is posted to the window. If a handshake request is received it means the extension is not installed.
|
|
14533
|
+
* @param event
|
|
14534
|
+
*/
|
|
14535
|
+
onWindowMessage(event) {
|
|
14536
|
+
this.logger.trace(this.platformAuthType + " - onWindowMessage called");
|
|
14537
|
+
// We only accept messages from ourselves
|
|
14538
|
+
if (event.source !== window) {
|
|
14539
|
+
return;
|
|
14540
|
+
}
|
|
14541
|
+
const request = event.data;
|
|
14542
|
+
if (!request.channel ||
|
|
14543
|
+
request.channel !== PlatformAuthConstants.CHANNEL_ID) {
|
|
14544
|
+
return;
|
|
14545
|
+
}
|
|
14546
|
+
if (request.extensionId && request.extensionId !== this.extensionId) {
|
|
14547
|
+
return;
|
|
14548
|
+
}
|
|
14549
|
+
if (request.body.method === NativeExtensionMethod.HandshakeRequest) {
|
|
14550
|
+
const handshakeResolver = this.handshakeResolvers.get(request.responseId);
|
|
14551
|
+
/*
|
|
14552
|
+
* Filter out responses with no matched resolvers sooner to keep channel ports open while waiting for
|
|
14553
|
+
* the proper response.
|
|
14554
|
+
*/
|
|
14555
|
+
if (!handshakeResolver) {
|
|
14556
|
+
this.logger.trace(this.platformAuthType +
|
|
14557
|
+
`.onWindowMessage - resolver can't be found for request ${request.responseId}`);
|
|
14558
|
+
return;
|
|
14559
|
+
}
|
|
14560
|
+
// If we receive this message back it means no extension intercepted the request, meaning no extension supporting handshake protocol is installed
|
|
14561
|
+
this.logger.verbose(request.extensionId
|
|
14562
|
+
? `Extension with id: ${request.extensionId} not installed`
|
|
14563
|
+
: "No extension installed");
|
|
14564
|
+
clearTimeout(this.timeoutId);
|
|
14565
|
+
this.messageChannel.port1.close();
|
|
14566
|
+
this.messageChannel.port2.close();
|
|
14567
|
+
window.removeEventListener("message", this.windowListener, false);
|
|
14568
|
+
this.handshakeEvent.end({
|
|
14569
|
+
success: false,
|
|
14570
|
+
extensionInstalled: false,
|
|
14571
|
+
});
|
|
14572
|
+
handshakeResolver.reject(createBrowserAuthError(nativeExtensionNotInstalled));
|
|
14573
|
+
}
|
|
14574
|
+
}
|
|
14575
|
+
/**
|
|
14576
|
+
* Invoked when a message is received from the extension on the MessageChannel port
|
|
14577
|
+
* @param event
|
|
14578
|
+
*/
|
|
14579
|
+
onChannelMessage(event) {
|
|
14580
|
+
this.logger.trace(this.platformAuthType + " - onChannelMessage called.");
|
|
14581
|
+
const request = event.data;
|
|
14582
|
+
const resolver = this.resolvers.get(request.responseId);
|
|
14583
|
+
const handshakeResolver = this.handshakeResolvers.get(request.responseId);
|
|
14584
|
+
try {
|
|
14585
|
+
const method = request.body.method;
|
|
14586
|
+
if (method === NativeExtensionMethod.Response) {
|
|
14587
|
+
if (!resolver) {
|
|
14588
|
+
return;
|
|
14589
|
+
}
|
|
14590
|
+
const response = request.body.response;
|
|
14591
|
+
this.logger.trace(this.platformAuthType +
|
|
14592
|
+
" - Received response from browser extension");
|
|
14593
|
+
this.logger.tracePii(this.platformAuthType +
|
|
14594
|
+
` - Received response from browser extension: ${JSON.stringify(response)}`);
|
|
14595
|
+
if (response.status !== "Success") {
|
|
14596
|
+
resolver.reject(createNativeAuthError(response.code, response.description, response.ext));
|
|
14597
|
+
}
|
|
14598
|
+
else if (response.result) {
|
|
14599
|
+
if (response.result["code"] &&
|
|
14600
|
+
response.result["description"]) {
|
|
14601
|
+
resolver.reject(createNativeAuthError(response.result["code"], response.result["description"], response.result["ext"]));
|
|
14602
|
+
}
|
|
14603
|
+
else {
|
|
14604
|
+
resolver.resolve(response.result);
|
|
14605
|
+
}
|
|
14606
|
+
}
|
|
14607
|
+
else {
|
|
14608
|
+
throw createAuthError(unexpectedError, "Event does not contain result.");
|
|
14609
|
+
}
|
|
14610
|
+
this.resolvers.delete(request.responseId);
|
|
14611
|
+
}
|
|
14612
|
+
else if (method === NativeExtensionMethod.HandshakeResponse) {
|
|
14613
|
+
if (!handshakeResolver) {
|
|
14614
|
+
this.logger.trace(this.platformAuthType +
|
|
14615
|
+
`.onChannelMessage - resolver can't be found for request ${request.responseId}`);
|
|
14616
|
+
return;
|
|
14617
|
+
}
|
|
14618
|
+
clearTimeout(this.timeoutId); // Clear setTimeout
|
|
14619
|
+
window.removeEventListener("message", this.windowListener, false); // Remove 'No extension' listener
|
|
14620
|
+
this.extensionId = request.extensionId;
|
|
14621
|
+
this.extensionVersion = request.body.version;
|
|
14622
|
+
this.logger.verbose(this.platformAuthType +
|
|
14623
|
+
` - Received HandshakeResponse from extension: ${this.extensionId}`);
|
|
14624
|
+
this.handshakeEvent.end({
|
|
14625
|
+
extensionInstalled: true,
|
|
14626
|
+
success: true,
|
|
14627
|
+
});
|
|
14628
|
+
handshakeResolver.resolve();
|
|
14629
|
+
this.handshakeResolvers.delete(request.responseId);
|
|
14630
|
+
}
|
|
14631
|
+
// Do nothing if method is not Response or HandshakeResponse
|
|
14632
|
+
}
|
|
14633
|
+
catch (err) {
|
|
14634
|
+
this.logger.error("Error parsing response from WAM Extension");
|
|
14635
|
+
this.logger.errorPii(`Error parsing response from WAM Extension: ${err}`);
|
|
14636
|
+
this.logger.errorPii(`Unable to parse ${event}`);
|
|
14637
|
+
if (resolver) {
|
|
14638
|
+
resolver.reject(err);
|
|
14639
|
+
}
|
|
14640
|
+
else if (handshakeResolver) {
|
|
14641
|
+
handshakeResolver.reject(err);
|
|
14642
|
+
}
|
|
14227
14643
|
}
|
|
14228
|
-
this.performanceClient.addFields({
|
|
14229
|
-
extensionId: this.nativeMessageHandler.getExtensionId(),
|
|
14230
|
-
extensionVersion: this.nativeMessageHandler.getExtensionVersion(),
|
|
14231
|
-
matsBrokerVersion: mats.broker_version,
|
|
14232
|
-
matsAccountJoinOnStart: mats.account_join_on_start,
|
|
14233
|
-
matsAccountJoinOnEnd: mats.account_join_on_end,
|
|
14234
|
-
matsDeviceJoin: mats.device_join,
|
|
14235
|
-
matsPromptBehavior: mats.prompt_behavior,
|
|
14236
|
-
matsApiErrorCode: mats.api_error_code,
|
|
14237
|
-
matsUiVisible: mats.ui_visible,
|
|
14238
|
-
matsSilentCode: mats.silent_code,
|
|
14239
|
-
matsSilentBiSubCode: mats.silent_bi_sub_code,
|
|
14240
|
-
matsSilentMessage: mats.silent_message,
|
|
14241
|
-
matsSilentStatus: mats.silent_status,
|
|
14242
|
-
matsHttpStatus: mats.http_status,
|
|
14243
|
-
matsHttpEventCount: mats.http_event_count,
|
|
14244
|
-
}, this.correlationId);
|
|
14245
|
-
return mats;
|
|
14246
14644
|
}
|
|
14247
14645
|
/**
|
|
14248
14646
|
* Validates native platform response before processing
|
|
14249
14647
|
* @param response
|
|
14250
14648
|
*/
|
|
14251
|
-
|
|
14649
|
+
validatePlatformBrokerResponse(response) {
|
|
14252
14650
|
if (response.hasOwnProperty("access_token") &&
|
|
14253
14651
|
response.hasOwnProperty("id_token") &&
|
|
14254
14652
|
response.hasOwnProperty("client_info") &&
|
|
@@ -14262,425 +14660,258 @@
|
|
|
14262
14660
|
}
|
|
14263
14661
|
}
|
|
14264
14662
|
/**
|
|
14265
|
-
*
|
|
14266
|
-
* @param response
|
|
14267
|
-
* @returns
|
|
14268
|
-
*/
|
|
14269
|
-
getMATSFromResponse(response) {
|
|
14270
|
-
if (response.properties.MATS) {
|
|
14271
|
-
try {
|
|
14272
|
-
return JSON.parse(response.properties.MATS);
|
|
14273
|
-
}
|
|
14274
|
-
catch (e) {
|
|
14275
|
-
this.logger.error("NativeInteractionClient - Error parsing MATS telemetry, returning null instead");
|
|
14276
|
-
}
|
|
14277
|
-
}
|
|
14278
|
-
return null;
|
|
14279
|
-
}
|
|
14280
|
-
/**
|
|
14281
|
-
* Returns whether or not response came from native cache
|
|
14282
|
-
* @param response
|
|
14663
|
+
* Returns the Id for the browser extension this handler is communicating with
|
|
14283
14664
|
* @returns
|
|
14284
14665
|
*/
|
|
14285
|
-
|
|
14286
|
-
|
|
14287
|
-
this.logger.verbose("NativeInteractionClient - MATS telemetry does not contain field indicating if response was served from cache. Returning false.");
|
|
14288
|
-
return false;
|
|
14289
|
-
}
|
|
14290
|
-
return !!mats.is_cached;
|
|
14291
|
-
}
|
|
14292
|
-
/**
|
|
14293
|
-
* Translates developer provided request object into NativeRequest object
|
|
14294
|
-
* @param request
|
|
14295
|
-
*/
|
|
14296
|
-
async initializeNativeRequest(request) {
|
|
14297
|
-
this.logger.trace("NativeInteractionClient - initializeNativeRequest called");
|
|
14298
|
-
const requestAuthority = request.authority || this.config.auth.authority;
|
|
14299
|
-
if (request.account) {
|
|
14300
|
-
// validate authority
|
|
14301
|
-
await this.getDiscoveredAuthority({
|
|
14302
|
-
requestAuthority,
|
|
14303
|
-
requestAzureCloudOptions: request.azureCloudOptions,
|
|
14304
|
-
account: request.account,
|
|
14305
|
-
});
|
|
14306
|
-
}
|
|
14307
|
-
const canonicalAuthority = new UrlString(requestAuthority);
|
|
14308
|
-
canonicalAuthority.validateAsUri();
|
|
14309
|
-
// 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.
|
|
14310
|
-
const { scopes, ...remainingProperties } = request;
|
|
14311
|
-
const scopeSet = new ScopeSet(scopes || []);
|
|
14312
|
-
scopeSet.appendScopes(OIDC_DEFAULT_SCOPES);
|
|
14313
|
-
const getPrompt = () => {
|
|
14314
|
-
// If request is silent, prompt is always none
|
|
14315
|
-
switch (this.apiId) {
|
|
14316
|
-
case ApiId.ssoSilent:
|
|
14317
|
-
case ApiId.acquireTokenSilent_silentFlow:
|
|
14318
|
-
this.logger.trace("initializeNativeRequest: silent request sets prompt to none");
|
|
14319
|
-
return PromptValue.NONE;
|
|
14320
|
-
}
|
|
14321
|
-
// Prompt not provided, request may proceed and native broker decides if it needs to prompt
|
|
14322
|
-
if (!request.prompt) {
|
|
14323
|
-
this.logger.trace("initializeNativeRequest: prompt was not provided");
|
|
14324
|
-
return undefined;
|
|
14325
|
-
}
|
|
14326
|
-
// If request is interactive, check if prompt provided is allowed to go directly to native broker
|
|
14327
|
-
switch (request.prompt) {
|
|
14328
|
-
case PromptValue.NONE:
|
|
14329
|
-
case PromptValue.CONSENT:
|
|
14330
|
-
case PromptValue.LOGIN:
|
|
14331
|
-
this.logger.trace("initializeNativeRequest: prompt is compatible with native flow");
|
|
14332
|
-
return request.prompt;
|
|
14333
|
-
default:
|
|
14334
|
-
this.logger.trace(`initializeNativeRequest: prompt = ${request.prompt} is not compatible with native flow`);
|
|
14335
|
-
throw createBrowserAuthError(nativePromptNotSupported);
|
|
14336
|
-
}
|
|
14337
|
-
};
|
|
14338
|
-
const validatedRequest = {
|
|
14339
|
-
...remainingProperties,
|
|
14340
|
-
accountId: this.accountId,
|
|
14341
|
-
clientId: this.config.auth.clientId,
|
|
14342
|
-
authority: canonicalAuthority.urlString,
|
|
14343
|
-
scope: scopeSet.printScopes(),
|
|
14344
|
-
redirectUri: this.getRedirectUri(request.redirectUri),
|
|
14345
|
-
prompt: getPrompt(),
|
|
14346
|
-
correlationId: this.correlationId,
|
|
14347
|
-
tokenType: request.authenticationScheme,
|
|
14348
|
-
windowTitleSubstring: document.title,
|
|
14349
|
-
extraParameters: {
|
|
14350
|
-
...request.extraQueryParameters,
|
|
14351
|
-
...request.tokenQueryParameters,
|
|
14352
|
-
},
|
|
14353
|
-
extendedExpiryToken: false,
|
|
14354
|
-
keyId: request.popKid,
|
|
14355
|
-
};
|
|
14356
|
-
// Check for PoP token requests: signPopToken should only be set to true if popKid is not set
|
|
14357
|
-
if (validatedRequest.signPopToken && !!request.popKid) {
|
|
14358
|
-
throw createBrowserAuthError(invalidPopTokenRequest);
|
|
14359
|
-
}
|
|
14360
|
-
this.handleExtraBrokerParams(validatedRequest);
|
|
14361
|
-
validatedRequest.extraParameters =
|
|
14362
|
-
validatedRequest.extraParameters || {};
|
|
14363
|
-
validatedRequest.extraParameters.telemetry =
|
|
14364
|
-
NativeConstants.MATS_TELEMETRY;
|
|
14365
|
-
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14366
|
-
// add POP request type
|
|
14367
|
-
const shrParameters = {
|
|
14368
|
-
resourceRequestUri: request.resourceRequestUri,
|
|
14369
|
-
resourceRequestMethod: request.resourceRequestMethod,
|
|
14370
|
-
shrClaims: request.shrClaims,
|
|
14371
|
-
shrNonce: request.shrNonce,
|
|
14372
|
-
};
|
|
14373
|
-
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto);
|
|
14374
|
-
// generate reqCnf if not provided in the request
|
|
14375
|
-
let reqCnfData;
|
|
14376
|
-
if (!validatedRequest.keyId) {
|
|
14377
|
-
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(shrParameters, this.logger);
|
|
14378
|
-
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14379
|
-
validatedRequest.keyId = generatedReqCnfData.kid;
|
|
14380
|
-
validatedRequest.signPopToken = true;
|
|
14381
|
-
}
|
|
14382
|
-
else {
|
|
14383
|
-
reqCnfData = this.browserCrypto.base64UrlEncode(JSON.stringify({ kid: validatedRequest.keyId }));
|
|
14384
|
-
validatedRequest.signPopToken = false;
|
|
14385
|
-
}
|
|
14386
|
-
// SPAs require whole string to be passed to broker
|
|
14387
|
-
validatedRequest.reqCnf = reqCnfData;
|
|
14388
|
-
}
|
|
14389
|
-
this.addRequestSKUs(validatedRequest);
|
|
14390
|
-
return validatedRequest;
|
|
14391
|
-
}
|
|
14392
|
-
/**
|
|
14393
|
-
* Handles extra broker request parameters
|
|
14394
|
-
* @param request {NativeTokenRequest}
|
|
14395
|
-
* @private
|
|
14396
|
-
*/
|
|
14397
|
-
handleExtraBrokerParams(request) {
|
|
14398
|
-
const hasExtraBrokerParams = request.extraParameters &&
|
|
14399
|
-
request.extraParameters.hasOwnProperty(BROKER_CLIENT_ID) &&
|
|
14400
|
-
request.extraParameters.hasOwnProperty(BROKER_REDIRECT_URI) &&
|
|
14401
|
-
request.extraParameters.hasOwnProperty(CLIENT_ID);
|
|
14402
|
-
if (!request.embeddedClientId && !hasExtraBrokerParams) {
|
|
14403
|
-
return;
|
|
14404
|
-
}
|
|
14405
|
-
let child_client_id = "";
|
|
14406
|
-
const child_redirect_uri = request.redirectUri;
|
|
14407
|
-
if (request.embeddedClientId) {
|
|
14408
|
-
request.redirectUri = this.config.auth.redirectUri;
|
|
14409
|
-
child_client_id = request.embeddedClientId;
|
|
14410
|
-
}
|
|
14411
|
-
else if (request.extraParameters) {
|
|
14412
|
-
request.redirectUri =
|
|
14413
|
-
request.extraParameters[BROKER_REDIRECT_URI];
|
|
14414
|
-
child_client_id =
|
|
14415
|
-
request.extraParameters[CLIENT_ID];
|
|
14416
|
-
}
|
|
14417
|
-
request.extraParameters = {
|
|
14418
|
-
child_client_id,
|
|
14419
|
-
child_redirect_uri,
|
|
14420
|
-
};
|
|
14421
|
-
this.performanceClient?.addFields({
|
|
14422
|
-
embeddedClientId: child_client_id,
|
|
14423
|
-
embeddedRedirectUri: child_redirect_uri,
|
|
14424
|
-
}, request.correlationId);
|
|
14425
|
-
}
|
|
14426
|
-
}
|
|
14427
|
-
|
|
14428
|
-
/*
|
|
14429
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14430
|
-
* Licensed under the MIT License.
|
|
14431
|
-
*/
|
|
14432
|
-
/**
|
|
14433
|
-
* Returns map of parameters that are applicable to all calls to /authorize whether using PKCE or EAR
|
|
14434
|
-
* @param config
|
|
14435
|
-
* @param authority
|
|
14436
|
-
* @param request
|
|
14437
|
-
* @param logger
|
|
14438
|
-
* @param performanceClient
|
|
14439
|
-
* @returns
|
|
14440
|
-
*/
|
|
14441
|
-
async function getStandardParameters(config, authority, request, logger, performanceClient) {
|
|
14442
|
-
const parameters = getStandardAuthorizeRequestParameters({ ...config.auth, authority: authority }, request, logger, performanceClient);
|
|
14443
|
-
addLibraryInfo(parameters, {
|
|
14444
|
-
sku: BrowserConstants.MSAL_SKU,
|
|
14445
|
-
version: version,
|
|
14446
|
-
os: "",
|
|
14447
|
-
cpu: "",
|
|
14448
|
-
});
|
|
14449
|
-
if (config.auth.protocolMode !== ProtocolMode.OIDC) {
|
|
14450
|
-
addApplicationTelemetry(parameters, config.telemetry.application);
|
|
14451
|
-
}
|
|
14452
|
-
if (request.platformBroker) {
|
|
14453
|
-
// signal ests that this is a WAM call
|
|
14454
|
-
addNativeBroker(parameters);
|
|
14455
|
-
// pass the req_cnf for POP
|
|
14456
|
-
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14457
|
-
const cryptoOps = new CryptoOps(logger, performanceClient);
|
|
14458
|
-
const popTokenGenerator = new PopTokenGenerator(cryptoOps);
|
|
14459
|
-
// req_cnf is always sent as a string for SPAs
|
|
14460
|
-
let reqCnfData;
|
|
14461
|
-
if (!request.popKid) {
|
|
14462
|
-
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, logger, performanceClient, request.correlationId)(request, logger);
|
|
14463
|
-
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14464
|
-
}
|
|
14465
|
-
else {
|
|
14466
|
-
reqCnfData = cryptoOps.encodeKid(request.popKid);
|
|
14467
|
-
}
|
|
14468
|
-
addPopToken(parameters, reqCnfData);
|
|
14469
|
-
}
|
|
14666
|
+
getExtensionId() {
|
|
14667
|
+
return this.extensionId;
|
|
14470
14668
|
}
|
|
14471
|
-
|
|
14472
|
-
|
|
14473
|
-
|
|
14474
|
-
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
* @param authority
|
|
14478
|
-
* @param request
|
|
14479
|
-
* @param logger
|
|
14480
|
-
* @param performanceClient
|
|
14481
|
-
* @returns
|
|
14482
|
-
*/
|
|
14483
|
-
async function getAuthCodeRequestUrl(config, authority, request, logger, performanceClient) {
|
|
14484
|
-
if (!request.codeChallenge) {
|
|
14485
|
-
throw createClientConfigurationError(pkceParamsMissing);
|
|
14669
|
+
/**
|
|
14670
|
+
* Returns the version for the browser extension this handler is communicating with
|
|
14671
|
+
* @returns
|
|
14672
|
+
*/
|
|
14673
|
+
getExtensionVersion() {
|
|
14674
|
+
return this.extensionVersion;
|
|
14486
14675
|
}
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
|
|
14490
|
-
|
|
14491
|
-
|
|
14492
|
-
|
|
14493
|
-
|
|
14494
|
-
* Gets the form that will be posted to /authorize with request parameters when using EAR
|
|
14495
|
-
*/
|
|
14496
|
-
async function getEARForm(frame, config, authority, request, logger, performanceClient) {
|
|
14497
|
-
if (!request.earJwk) {
|
|
14498
|
-
throw createBrowserAuthError(earJwkEmpty);
|
|
14676
|
+
getExtensionName() {
|
|
14677
|
+
return this.getExtensionId() ===
|
|
14678
|
+
PlatformAuthConstants.PREFERRED_EXTENSION_ID
|
|
14679
|
+
? "chrome"
|
|
14680
|
+
: this.getExtensionId()?.length
|
|
14681
|
+
? "unknown"
|
|
14682
|
+
: undefined;
|
|
14499
14683
|
}
|
|
14500
|
-
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
|
|
14504
|
-
|
|
14505
|
-
const url = getAuthorizeUrl(authority, queryParams, config.auth.encodeExtraQueryParams, request.extraQueryParameters);
|
|
14506
|
-
return createForm(frame, url, parameters);
|
|
14507
|
-
}
|
|
14508
|
-
/**
|
|
14509
|
-
* Creates form element in the provided document with auth parameters in the post body
|
|
14510
|
-
* @param frame
|
|
14511
|
-
* @param authorizeUrl
|
|
14512
|
-
* @param parameters
|
|
14513
|
-
* @returns
|
|
14514
|
-
*/
|
|
14515
|
-
function createForm(frame, authorizeUrl, parameters) {
|
|
14516
|
-
const form = frame.createElement("form");
|
|
14517
|
-
form.method = "post";
|
|
14518
|
-
form.action = authorizeUrl;
|
|
14519
|
-
parameters.forEach((value, key) => {
|
|
14520
|
-
const param = frame.createElement("input");
|
|
14521
|
-
param.hidden = true;
|
|
14522
|
-
param.name = key;
|
|
14523
|
-
param.value = value;
|
|
14524
|
-
form.appendChild(param);
|
|
14525
|
-
});
|
|
14526
|
-
frame.body.appendChild(form);
|
|
14527
|
-
return form;
|
|
14528
|
-
}
|
|
14529
|
-
/**
|
|
14530
|
-
* Response handler when server returns accountId on the /authorize request
|
|
14531
|
-
* @param request
|
|
14532
|
-
* @param accountId
|
|
14533
|
-
* @param apiId
|
|
14534
|
-
* @param config
|
|
14535
|
-
* @param browserStorage
|
|
14536
|
-
* @param nativeStorage
|
|
14537
|
-
* @param eventHandler
|
|
14538
|
-
* @param logger
|
|
14539
|
-
* @param performanceClient
|
|
14540
|
-
* @param nativeMessageHandler
|
|
14541
|
-
* @returns
|
|
14684
|
+
}
|
|
14685
|
+
|
|
14686
|
+
/*
|
|
14687
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14688
|
+
* Licensed under the MIT License.
|
|
14542
14689
|
*/
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14690
|
+
class PlatformAuthDOMHandler {
|
|
14691
|
+
constructor(logger, performanceClient, correlationId) {
|
|
14692
|
+
this.logger = logger;
|
|
14693
|
+
this.performanceClient = performanceClient;
|
|
14694
|
+
this.correlationId = correlationId;
|
|
14695
|
+
this.platformAuthType = PlatformAuthConstants.PLATFORM_DOM_PROVIDER;
|
|
14546
14696
|
}
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
|
|
14556
|
-
|
|
14557
|
-
|
|
14558
|
-
|
|
14559
|
-
|
|
14560
|
-
* @param codeVerifier
|
|
14561
|
-
* @param authClient
|
|
14562
|
-
* @param browserStorage
|
|
14563
|
-
* @param logger
|
|
14564
|
-
* @param performanceClient
|
|
14565
|
-
* @returns
|
|
14566
|
-
*/
|
|
14567
|
-
async function handleResponseCode(request, response, codeVerifier, apiId, config, authClient, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler) {
|
|
14568
|
-
// Remove throttle if it exists
|
|
14569
|
-
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14570
|
-
if (response.accountId) {
|
|
14571
|
-
return invokeAsync(handleResponsePlatformBroker, PerformanceEvents.HandleResponsePlatformBroker, logger, performanceClient, request.correlationId)(request, response.accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler);
|
|
14697
|
+
static async createProvider(logger, performanceClient, correlationId) {
|
|
14698
|
+
logger.trace("PlatformAuthDOMHandler: createProvider called");
|
|
14699
|
+
// @ts-ignore
|
|
14700
|
+
if (window.navigator?.platformAuthentication) {
|
|
14701
|
+
const supportedContracts =
|
|
14702
|
+
// @ts-ignore
|
|
14703
|
+
await window.navigator.platformAuthentication.getSupportedContracts(PlatformAuthConstants.MICROSOFT_ENTRA_BROKERID);
|
|
14704
|
+
if (supportedContracts?.includes(PlatformAuthConstants.PLATFORM_DOM_APIS)) {
|
|
14705
|
+
logger.trace("Platform auth api available in DOM");
|
|
14706
|
+
return new PlatformAuthDOMHandler(logger, performanceClient, correlationId);
|
|
14707
|
+
}
|
|
14708
|
+
}
|
|
14709
|
+
return undefined;
|
|
14572
14710
|
}
|
|
14573
|
-
|
|
14574
|
-
|
|
14575
|
-
|
|
14576
|
-
|
|
14577
|
-
|
|
14578
|
-
|
|
14579
|
-
const interactionHandler = new InteractionHandler(authClient, browserStorage, authCodeRequest, logger, performanceClient);
|
|
14580
|
-
// Handle response from hash string.
|
|
14581
|
-
const result = await invokeAsync(interactionHandler.handleCodeResponse.bind(interactionHandler), PerformanceEvents.HandleCodeResponse, logger, performanceClient, request.correlationId)(response, request);
|
|
14582
|
-
return result;
|
|
14583
|
-
}
|
|
14584
|
-
/**
|
|
14585
|
-
* Response handler when server returns ear_jwe on the /authorize request
|
|
14586
|
-
* @param request
|
|
14587
|
-
* @param response
|
|
14588
|
-
* @param apiId
|
|
14589
|
-
* @param config
|
|
14590
|
-
* @param authority
|
|
14591
|
-
* @param browserStorage
|
|
14592
|
-
* @param nativeStorage
|
|
14593
|
-
* @param eventHandler
|
|
14594
|
-
* @param logger
|
|
14595
|
-
* @param performanceClient
|
|
14596
|
-
* @param nativeMessageHandler
|
|
14597
|
-
* @returns
|
|
14598
|
-
*/
|
|
14599
|
-
async function handleResponseEAR(request, response, apiId, config, authority, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler) {
|
|
14600
|
-
// Remove throttle if it exists
|
|
14601
|
-
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14602
|
-
// Validate state & check response for errors
|
|
14603
|
-
validateAuthorizationResponse(response, request.state);
|
|
14604
|
-
if (!response.ear_jwe) {
|
|
14605
|
-
throw createBrowserAuthError(earJweEmpty);
|
|
14711
|
+
/**
|
|
14712
|
+
* Returns the Id for the broker extension this handler is communicating with
|
|
14713
|
+
* @returns
|
|
14714
|
+
*/
|
|
14715
|
+
getExtensionId() {
|
|
14716
|
+
return PlatformAuthConstants.MICROSOFT_ENTRA_BROKERID;
|
|
14606
14717
|
}
|
|
14607
|
-
|
|
14608
|
-
|
|
14718
|
+
getExtensionVersion() {
|
|
14719
|
+
return "";
|
|
14609
14720
|
}
|
|
14610
|
-
|
|
14611
|
-
|
|
14612
|
-
|
|
14721
|
+
getExtensionName() {
|
|
14722
|
+
return PlatformAuthConstants.DOM_API_NAME;
|
|
14723
|
+
}
|
|
14724
|
+
/**
|
|
14725
|
+
* Send token request to platform broker via browser DOM API
|
|
14726
|
+
* @param request
|
|
14727
|
+
* @returns
|
|
14728
|
+
*/
|
|
14729
|
+
async sendMessage(request) {
|
|
14730
|
+
this.logger.trace(this.platformAuthType + " - Sending request to browser DOM API");
|
|
14731
|
+
try {
|
|
14732
|
+
const platformDOMRequest = this.initializePlatformDOMRequest(request);
|
|
14733
|
+
const response =
|
|
14734
|
+
// @ts-ignore
|
|
14735
|
+
await window.navigator.platformAuthentication.executeGetToken(platformDOMRequest);
|
|
14736
|
+
return this.validatePlatformBrokerResponse(response);
|
|
14737
|
+
}
|
|
14738
|
+
catch (e) {
|
|
14739
|
+
this.logger.error(this.platformAuthType + " - executeGetToken DOM API error");
|
|
14740
|
+
throw e;
|
|
14741
|
+
}
|
|
14742
|
+
}
|
|
14743
|
+
initializePlatformDOMRequest(request) {
|
|
14744
|
+
this.logger.trace(this.platformAuthType + " - initializeNativeDOMRequest called");
|
|
14745
|
+
const { accountId, clientId, authority, scope, redirectUri, correlationId, state, storeInCache, embeddedClientId, extraParameters, ...remainingProperties } = request;
|
|
14746
|
+
const validExtraParameters = this.getDOMExtraParams(remainingProperties);
|
|
14747
|
+
const platformDOMRequest = {
|
|
14748
|
+
accountId: accountId,
|
|
14749
|
+
brokerId: this.getExtensionId(),
|
|
14750
|
+
authority: authority,
|
|
14751
|
+
clientId: clientId,
|
|
14752
|
+
correlationId: correlationId || this.correlationId,
|
|
14753
|
+
extraParameters: { ...extraParameters, ...validExtraParameters },
|
|
14754
|
+
isSecurityTokenService: false,
|
|
14755
|
+
redirectUri: redirectUri,
|
|
14756
|
+
scope: scope,
|
|
14757
|
+
state: state,
|
|
14758
|
+
storeInCache: storeInCache,
|
|
14759
|
+
embeddedClientId: embeddedClientId,
|
|
14760
|
+
};
|
|
14761
|
+
return platformDOMRequest;
|
|
14762
|
+
}
|
|
14763
|
+
validatePlatformBrokerResponse(response) {
|
|
14764
|
+
if (response.hasOwnProperty("isSuccess")) {
|
|
14765
|
+
if (response.hasOwnProperty("accessToken") &&
|
|
14766
|
+
response.hasOwnProperty("idToken") &&
|
|
14767
|
+
response.hasOwnProperty("clientInfo") &&
|
|
14768
|
+
response.hasOwnProperty("account") &&
|
|
14769
|
+
response.hasOwnProperty("scopes") &&
|
|
14770
|
+
response.hasOwnProperty("expiresIn")) {
|
|
14771
|
+
this.logger.trace(this.platformAuthType +
|
|
14772
|
+
" - platform broker returned successful and valid response");
|
|
14773
|
+
return this.convertToPlatformBrokerResponse(response);
|
|
14774
|
+
}
|
|
14775
|
+
else if (response.hasOwnProperty("error")) {
|
|
14776
|
+
const errorResponse = response;
|
|
14777
|
+
if (errorResponse.isSuccess === false &&
|
|
14778
|
+
errorResponse.error &&
|
|
14779
|
+
errorResponse.error.code) {
|
|
14780
|
+
this.logger.trace(this.platformAuthType +
|
|
14781
|
+
" - platform broker returned error response");
|
|
14782
|
+
throw createNativeAuthError(errorResponse.error.code, errorResponse.error.description, {
|
|
14783
|
+
error: parseInt(errorResponse.error.errorCode),
|
|
14784
|
+
protocol_error: errorResponse.error.protocolError,
|
|
14785
|
+
status: errorResponse.error.status,
|
|
14786
|
+
properties: errorResponse.error.properties,
|
|
14787
|
+
});
|
|
14788
|
+
}
|
|
14789
|
+
}
|
|
14790
|
+
}
|
|
14791
|
+
throw createAuthError(unexpectedError, "Response missing expected properties.");
|
|
14792
|
+
}
|
|
14793
|
+
convertToPlatformBrokerResponse(response) {
|
|
14794
|
+
this.logger.trace(this.platformAuthType + " - convertToNativeResponse called");
|
|
14795
|
+
const nativeResponse = {
|
|
14796
|
+
access_token: response.accessToken,
|
|
14797
|
+
id_token: response.idToken,
|
|
14798
|
+
client_info: response.clientInfo,
|
|
14799
|
+
account: response.account,
|
|
14800
|
+
expires_in: response.expiresIn,
|
|
14801
|
+
scope: response.scopes,
|
|
14802
|
+
state: response.state || "",
|
|
14803
|
+
properties: response.properties || {},
|
|
14804
|
+
extendedLifetimeToken: response.extendedLifetimeToken ?? false,
|
|
14805
|
+
shr: response.proofOfPossessionPayload,
|
|
14806
|
+
};
|
|
14807
|
+
return nativeResponse;
|
|
14808
|
+
}
|
|
14809
|
+
getDOMExtraParams(extraParameters) {
|
|
14810
|
+
const stringifiedParams = Object.entries(extraParameters).reduce((record, [key, value]) => {
|
|
14811
|
+
record[key] = String(value);
|
|
14812
|
+
return record;
|
|
14813
|
+
}, {});
|
|
14814
|
+
const validExtraParams = {
|
|
14815
|
+
...stringifiedParams,
|
|
14816
|
+
};
|
|
14817
|
+
return validExtraParams;
|
|
14613
14818
|
}
|
|
14614
|
-
const responseHandler = new ResponseHandler(config.auth.clientId, browserStorage, new CryptoOps(logger, performanceClient), logger, null, null, performanceClient);
|
|
14615
|
-
// Validate response. This function throws a server error if an error is returned by the server.
|
|
14616
|
-
responseHandler.validateTokenResponse(decryptedData);
|
|
14617
|
-
// Temporary until response handler is refactored to be more flow agnostic.
|
|
14618
|
-
const additionalData = {
|
|
14619
|
-
code: "",
|
|
14620
|
-
state: request.state,
|
|
14621
|
-
nonce: request.nonce,
|
|
14622
|
-
client_info: decryptedData.client_info,
|
|
14623
|
-
cloud_graph_host_name: decryptedData.cloud_graph_host_name,
|
|
14624
|
-
cloud_instance_host_name: decryptedData.cloud_instance_host_name,
|
|
14625
|
-
cloud_instance_name: decryptedData.cloud_instance_name,
|
|
14626
|
-
msgraph_host: decryptedData.msgraph_host,
|
|
14627
|
-
};
|
|
14628
|
-
return (await invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), PerformanceEvents.HandleServerTokenResponse, logger, performanceClient, request.correlationId)(decryptedData, authority, nowSeconds(), request, additionalData, undefined, undefined, undefined, undefined));
|
|
14629
14819
|
}
|
|
14630
14820
|
|
|
14631
14821
|
/*
|
|
14632
14822
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14633
14823
|
* Licensed under the MIT License.
|
|
14634
14824
|
*/
|
|
14635
|
-
// Constant byte array length
|
|
14636
|
-
const RANDOM_BYTE_ARR_LENGTH = 32;
|
|
14637
|
-
/**
|
|
14638
|
-
* This file defines APIs to generate PKCE codes and code verifiers.
|
|
14639
|
-
*/
|
|
14640
14825
|
/**
|
|
14641
|
-
*
|
|
14826
|
+
* Checks if the platform broker is available in the current environment.
|
|
14827
|
+
* @param loggerOptions
|
|
14828
|
+
* @param perfClient
|
|
14829
|
+
* @returns
|
|
14642
14830
|
*/
|
|
14643
|
-
async function
|
|
14644
|
-
|
|
14645
|
-
|
|
14646
|
-
const
|
|
14647
|
-
|
|
14648
|
-
|
|
14649
|
-
|
|
14650
|
-
}
|
|
14831
|
+
async function isPlatformBrokerAvailable(loggerOptions, perfClient, correlationId) {
|
|
14832
|
+
const logger = new Logger(loggerOptions || {}, name, version);
|
|
14833
|
+
logger.trace("isPlatformBrokerAvailable called");
|
|
14834
|
+
const performanceClient = perfClient || new StubPerformanceClient();
|
|
14835
|
+
if (typeof window === "undefined") {
|
|
14836
|
+
logger.trace("Non-browser environment detected, returning false");
|
|
14837
|
+
return false;
|
|
14838
|
+
}
|
|
14839
|
+
return !!(await getPlatformAuthProvider(logger, performanceClient, correlationId || createNewGuid()));
|
|
14651
14840
|
}
|
|
14652
|
-
|
|
14653
|
-
|
|
14654
|
-
|
|
14655
|
-
|
|
14656
|
-
|
|
14841
|
+
async function getPlatformAuthProvider(logger, performanceClient, correlationId, nativeBrokerHandshakeTimeout) {
|
|
14842
|
+
logger.trace("getPlatformAuthProvider called", correlationId);
|
|
14843
|
+
const enablePlatformBrokerDOMSupport = isDomEnabledForPlatformAuth();
|
|
14844
|
+
logger.trace("Has client allowed platform auth via DOM API: " +
|
|
14845
|
+
enablePlatformBrokerDOMSupport);
|
|
14846
|
+
let platformAuthProvider;
|
|
14657
14847
|
try {
|
|
14658
|
-
|
|
14659
|
-
|
|
14660
|
-
|
|
14661
|
-
|
|
14662
|
-
|
|
14663
|
-
|
|
14848
|
+
if (enablePlatformBrokerDOMSupport) {
|
|
14849
|
+
// Check if DOM platform API is supported first
|
|
14850
|
+
platformAuthProvider = await PlatformAuthDOMHandler.createProvider(logger, performanceClient, correlationId);
|
|
14851
|
+
}
|
|
14852
|
+
if (!platformAuthProvider) {
|
|
14853
|
+
logger.trace("Platform auth via DOM API not available, checking for extension");
|
|
14854
|
+
/*
|
|
14855
|
+
* If DOM APIs are not available, check if browser extension is available.
|
|
14856
|
+
* Platform authentication via DOM APIs is preferred over extension APIs.
|
|
14857
|
+
*/
|
|
14858
|
+
platformAuthProvider =
|
|
14859
|
+
await PlatformAuthExtensionHandler.createProvider(logger, nativeBrokerHandshakeTimeout ||
|
|
14860
|
+
DEFAULT_NATIVE_BROKER_HANDSHAKE_TIMEOUT_MS, performanceClient);
|
|
14861
|
+
}
|
|
14664
14862
|
}
|
|
14665
14863
|
catch (e) {
|
|
14666
|
-
|
|
14864
|
+
logger.trace("Platform auth not available", e);
|
|
14667
14865
|
}
|
|
14866
|
+
return platformAuthProvider;
|
|
14668
14867
|
}
|
|
14669
14868
|
/**
|
|
14670
|
-
*
|
|
14671
|
-
*
|
|
14869
|
+
* Returns true if the DOM API support for platform auth is enabled in session storage
|
|
14870
|
+
* @returns boolean
|
|
14871
|
+
* @deprecated
|
|
14672
14872
|
*/
|
|
14673
|
-
|
|
14674
|
-
|
|
14873
|
+
function isDomEnabledForPlatformAuth() {
|
|
14874
|
+
let sessionStorage;
|
|
14675
14875
|
try {
|
|
14676
|
-
|
|
14677
|
-
|
|
14678
|
-
|
|
14679
|
-
return urlEncodeArr(new Uint8Array(pkceHashedCodeVerifier));
|
|
14876
|
+
sessionStorage = window[BrowserCacheLocation.SessionStorage];
|
|
14877
|
+
// Mute errors if it's a non-browser environment or cookies are blocked.
|
|
14878
|
+
return sessionStorage?.getItem(PLATFORM_AUTH_DOM_SUPPORT) === "true";
|
|
14680
14879
|
}
|
|
14681
14880
|
catch (e) {
|
|
14682
|
-
|
|
14881
|
+
return false;
|
|
14882
|
+
}
|
|
14883
|
+
}
|
|
14884
|
+
/**
|
|
14885
|
+
* Returns boolean indicating whether or not the request should attempt to use native broker
|
|
14886
|
+
* @param logger
|
|
14887
|
+
* @param config
|
|
14888
|
+
* @param platformAuthProvider
|
|
14889
|
+
* @param authenticationScheme
|
|
14890
|
+
*/
|
|
14891
|
+
function isPlatformAuthAllowed(config, logger, platformAuthProvider, authenticationScheme) {
|
|
14892
|
+
logger.trace("isBrokerAvailable called");
|
|
14893
|
+
if (!config.system.allowPlatformBroker) {
|
|
14894
|
+
logger.trace("isBrokerAvailable: allowPlatformBroker is not enabled, returning false");
|
|
14895
|
+
// Developer disabled WAM
|
|
14896
|
+
return false;
|
|
14897
|
+
}
|
|
14898
|
+
if (!platformAuthProvider) {
|
|
14899
|
+
logger.trace("isBrokerAvailable: Platform auth provider is not initialized, returning false");
|
|
14900
|
+
// Platform broker auth providers are not available
|
|
14901
|
+
return false;
|
|
14902
|
+
}
|
|
14903
|
+
if (authenticationScheme) {
|
|
14904
|
+
switch (authenticationScheme) {
|
|
14905
|
+
case AuthenticationScheme.BEARER:
|
|
14906
|
+
case AuthenticationScheme.POP:
|
|
14907
|
+
logger.trace("isBrokerAvailable: authenticationScheme is supported, returning true");
|
|
14908
|
+
return true;
|
|
14909
|
+
default:
|
|
14910
|
+
logger.trace("isBrokerAvailable: authenticationScheme is not supported, returning false");
|
|
14911
|
+
return false;
|
|
14912
|
+
}
|
|
14683
14913
|
}
|
|
14914
|
+
return true;
|
|
14684
14915
|
}
|
|
14685
14916
|
|
|
14686
14917
|
/*
|
|
@@ -14688,8 +14919,8 @@
|
|
|
14688
14919
|
* Licensed under the MIT License.
|
|
14689
14920
|
*/
|
|
14690
14921
|
class PopupClient extends StandardInteractionClient {
|
|
14691
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl,
|
|
14692
|
-
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
14922
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl, platformAuthHandler, correlationId) {
|
|
14923
|
+
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthHandler, correlationId);
|
|
14693
14924
|
// Properly sets this reference for the unload event.
|
|
14694
14925
|
this.unloadWindow = this.unloadWindow.bind(this);
|
|
14695
14926
|
this.nativeStorage = nativeStorageImpl;
|
|
@@ -14777,7 +15008,7 @@
|
|
|
14777
15008
|
if (popupParams.popup) {
|
|
14778
15009
|
preconnect(validRequest.authority);
|
|
14779
15010
|
}
|
|
14780
|
-
const isPlatformBroker =
|
|
15011
|
+
const isPlatformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, request.authenticationScheme);
|
|
14781
15012
|
validRequest.platformBroker = isPlatformBroker;
|
|
14782
15013
|
if (this.config.auth.protocolMode === ProtocolMode.EAR) {
|
|
14783
15014
|
return this.executeEarFlow(validRequest, popupParams);
|
|
@@ -14819,7 +15050,7 @@
|
|
|
14819
15050
|
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
|
|
14820
15051
|
const responseString = await this.monitorPopupForHash(popupWindow, popupParams.popupWindowParent);
|
|
14821
15052
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.serverResponseType, this.logger);
|
|
14822
|
-
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.
|
|
15053
|
+
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);
|
|
14823
15054
|
}
|
|
14824
15055
|
catch (e) {
|
|
14825
15056
|
// Close the synchronous popup if an error is thrown before the window unload event is registered
|
|
@@ -14855,7 +15086,7 @@
|
|
|
14855
15086
|
// Monitor the popup for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
|
|
14856
15087
|
const responseString = await invokeAsync(this.monitorPopupForHash.bind(this), PerformanceEvents.SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(popupWindow, popupParams.popupWindowParent);
|
|
14857
15088
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.serverResponseType, this.logger);
|
|
14858
|
-
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.
|
|
15089
|
+
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);
|
|
14859
15090
|
}
|
|
14860
15091
|
/**
|
|
14861
15092
|
*
|
|
@@ -15152,8 +15383,8 @@
|
|
|
15152
15383
|
return navigation?.type;
|
|
15153
15384
|
}
|
|
15154
15385
|
class RedirectClient extends StandardInteractionClient {
|
|
15155
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl,
|
|
15156
|
-
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
15386
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl, platformAuthHandler, correlationId) {
|
|
15387
|
+
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthHandler, correlationId);
|
|
15157
15388
|
this.nativeStorage = nativeStorageImpl;
|
|
15158
15389
|
}
|
|
15159
15390
|
/**
|
|
@@ -15162,8 +15393,7 @@
|
|
|
15162
15393
|
*/
|
|
15163
15394
|
async acquireToken(request) {
|
|
15164
15395
|
const validRequest = await invokeAsync(this.initializeAuthorizationRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(request, exports.InteractionType.Redirect);
|
|
15165
|
-
validRequest.platformBroker =
|
|
15166
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeMessageHandler, request.authenticationScheme);
|
|
15396
|
+
validRequest.platformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, request.authenticationScheme);
|
|
15167
15397
|
const handleBackButton = (event) => {
|
|
15168
15398
|
// Clear temporary cache if the back button is clicked during the redirect flow.
|
|
15169
15399
|
if (event.persisted) {
|
|
@@ -15403,10 +15633,10 @@
|
|
|
15403
15633
|
requestExtraQueryParameters: request.extraQueryParameters,
|
|
15404
15634
|
account: request.account,
|
|
15405
15635
|
});
|
|
15406
|
-
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.
|
|
15636
|
+
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);
|
|
15407
15637
|
}
|
|
15408
15638
|
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), PerformanceEvents.StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)({ serverTelemetryManager, requestAuthority: request.authority });
|
|
15409
|
-
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.
|
|
15639
|
+
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);
|
|
15410
15640
|
}
|
|
15411
15641
|
/**
|
|
15412
15642
|
* Redirects window to given URL.
|
|
@@ -15690,8 +15920,8 @@
|
|
|
15690
15920
|
* Licensed under the MIT License.
|
|
15691
15921
|
*/
|
|
15692
15922
|
class SilentIframeClient extends StandardInteractionClient {
|
|
15693
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, nativeStorageImpl,
|
|
15694
|
-
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
15923
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, nativeStorageImpl, platformAuthProvider, correlationId) {
|
|
15924
|
+
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthProvider, correlationId);
|
|
15695
15925
|
this.apiId = apiId;
|
|
15696
15926
|
this.nativeStorage = nativeStorageImpl;
|
|
15697
15927
|
}
|
|
@@ -15721,8 +15951,7 @@
|
|
|
15721
15951
|
}
|
|
15722
15952
|
// Create silent request
|
|
15723
15953
|
const silentRequest = await invokeAsync(this.initializeAuthorizationRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, request.correlationId)(inputRequest, exports.InteractionType.Silent);
|
|
15724
|
-
silentRequest.platformBroker =
|
|
15725
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeMessageHandler, silentRequest.authenticationScheme);
|
|
15954
|
+
silentRequest.platformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, silentRequest.authenticationScheme);
|
|
15726
15955
|
preconnect(silentRequest.authority);
|
|
15727
15956
|
if (this.config.auth.protocolMode === ProtocolMode.EAR) {
|
|
15728
15957
|
return this.executeEarFlow(silentRequest);
|
|
@@ -15788,7 +16017,7 @@
|
|
|
15788
16017
|
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
|
|
15789
16018
|
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);
|
|
15790
16019
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, correlationId)(responseString, responseType, this.logger);
|
|
15791
|
-
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.
|
|
16020
|
+
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);
|
|
15792
16021
|
}
|
|
15793
16022
|
/**
|
|
15794
16023
|
* Currently Unsupported
|
|
@@ -15819,7 +16048,7 @@
|
|
|
15819
16048
|
// Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
|
|
15820
16049
|
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);
|
|
15821
16050
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, correlationId)(responseString, responseType, this.logger);
|
|
15822
|
-
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.
|
|
16051
|
+
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);
|
|
15823
16052
|
}
|
|
15824
16053
|
}
|
|
15825
16054
|
|
|
@@ -16100,8 +16329,8 @@
|
|
|
16100
16329
|
* Licensed under the MIT License.
|
|
16101
16330
|
*/
|
|
16102
16331
|
class SilentAuthCodeClient extends StandardInteractionClient {
|
|
16103
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient,
|
|
16104
|
-
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
16332
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, platformAuthProvider, correlationId) {
|
|
16333
|
+
super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthProvider, correlationId);
|
|
16105
16334
|
this.apiId = apiId;
|
|
16106
16335
|
}
|
|
16107
16336
|
/**
|
|
@@ -16159,6 +16388,25 @@
|
|
|
16159
16388
|
}
|
|
16160
16389
|
}
|
|
16161
16390
|
|
|
16391
|
+
/*
|
|
16392
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
16393
|
+
* Licensed under the MIT License.
|
|
16394
|
+
*/
|
|
16395
|
+
function collectInstanceStats(currentClientId, performanceEvent, logger) {
|
|
16396
|
+
const frameInstances =
|
|
16397
|
+
// @ts-ignore
|
|
16398
|
+
window.msal?.clientIds || [];
|
|
16399
|
+
const msalInstanceCount = frameInstances.length;
|
|
16400
|
+
const sameClientIdInstanceCount = frameInstances.filter((i) => i === currentClientId).length;
|
|
16401
|
+
if (sameClientIdInstanceCount > 1) {
|
|
16402
|
+
logger.warning("There is already an instance of MSAL.js in the window with the same client id.");
|
|
16403
|
+
}
|
|
16404
|
+
performanceEvent.add({
|
|
16405
|
+
msalInstanceCount: msalInstanceCount,
|
|
16406
|
+
sameClientIdInstanceCount: sameClientIdInstanceCount,
|
|
16407
|
+
});
|
|
16408
|
+
}
|
|
16409
|
+
|
|
16162
16410
|
/*
|
|
16163
16411
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
16164
16412
|
* Licensed under the MIT License.
|
|
@@ -16270,7 +16518,7 @@
|
|
|
16270
16518
|
* Initializer function to perform async startup tasks such as connecting to WAM extension
|
|
16271
16519
|
* @param request {?InitializeApplicationRequest} correlation id
|
|
16272
16520
|
*/
|
|
16273
|
-
async initialize(request) {
|
|
16521
|
+
async initialize(request, isBroker) {
|
|
16274
16522
|
this.logger.trace("initialize called");
|
|
16275
16523
|
if (this.initialized) {
|
|
16276
16524
|
this.logger.info("initialize has already been called, exiting early.");
|
|
@@ -16286,11 +16534,18 @@
|
|
|
16286
16534
|
const allowPlatformBroker = this.config.system.allowPlatformBroker;
|
|
16287
16535
|
const initMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.InitializeClientApplication, initCorrelationId);
|
|
16288
16536
|
this.eventHandler.emitEvent(EventType.INITIALIZE_START);
|
|
16537
|
+
// Broker applications are initialized twice, so we avoid double-counting it
|
|
16538
|
+
if (!isBroker) {
|
|
16539
|
+
try {
|
|
16540
|
+
this.logMultipleInstances(initMeasurement);
|
|
16541
|
+
}
|
|
16542
|
+
catch { }
|
|
16543
|
+
}
|
|
16289
16544
|
await invokeAsync(this.browserStorage.initialize.bind(this.browserStorage), PerformanceEvents.InitializeCache, this.logger, this.performanceClient, initCorrelationId)(initCorrelationId);
|
|
16290
16545
|
if (allowPlatformBroker) {
|
|
16291
16546
|
try {
|
|
16292
|
-
|
|
16293
|
-
|
|
16547
|
+
// check if platform authentication is available via DOM or browser extension and create relevant handlers
|
|
16548
|
+
this.platformAuthProvider = await getPlatformAuthProvider(this.logger, this.performanceClient, initCorrelationId, this.config.system.nativeBrokerHandshakeTimeout);
|
|
16294
16549
|
}
|
|
16295
16550
|
catch (e) {
|
|
16296
16551
|
this.logger.verbose(e);
|
|
@@ -16360,18 +16615,15 @@
|
|
|
16360
16615
|
}
|
|
16361
16616
|
const loggedInAccounts = this.getAllAccounts();
|
|
16362
16617
|
const platformBrokerRequest = this.browserStorage.getCachedNativeRequest();
|
|
16363
|
-
const useNative = platformBrokerRequest &&
|
|
16364
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeExtensionProvider) &&
|
|
16365
|
-
this.nativeExtensionProvider &&
|
|
16366
|
-
!hash;
|
|
16618
|
+
const useNative = platformBrokerRequest && this.platformAuthProvider && !hash;
|
|
16367
16619
|
let rootMeasurement;
|
|
16368
16620
|
this.eventHandler.emitEvent(EventType.HANDLE_REDIRECT_START, exports.InteractionType.Redirect);
|
|
16369
16621
|
let redirectResponse;
|
|
16370
16622
|
try {
|
|
16371
|
-
if (useNative && this.
|
|
16623
|
+
if (useNative && this.platformAuthProvider) {
|
|
16372
16624
|
rootMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenRedirect, platformBrokerRequest?.correlationId || "");
|
|
16373
16625
|
this.logger.trace("handleRedirectPromise - acquiring token from native platform");
|
|
16374
|
-
const nativeClient = new
|
|
16626
|
+
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);
|
|
16375
16627
|
redirectResponse = invokeAsync(nativeClient.handleRedirectPromise.bind(nativeClient), PerformanceEvents.HandleNativeRedirectPromiseMeasurement, this.logger, this.performanceClient, rootMeasurement.event.correlationId)(this.performanceClient, rootMeasurement.event.correlationId);
|
|
16376
16628
|
}
|
|
16377
16629
|
else {
|
|
@@ -16500,15 +16752,15 @@
|
|
|
16500
16752
|
this.eventHandler.emitEvent(EventType.LOGIN_START, exports.InteractionType.Redirect, request);
|
|
16501
16753
|
}
|
|
16502
16754
|
let result;
|
|
16503
|
-
if (this.
|
|
16755
|
+
if (this.platformAuthProvider &&
|
|
16504
16756
|
this.canUsePlatformBroker(request)) {
|
|
16505
|
-
const nativeClient = new
|
|
16757
|
+
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);
|
|
16506
16758
|
result = nativeClient
|
|
16507
16759
|
.acquireTokenRedirect(request, atrMeasurement)
|
|
16508
16760
|
.catch((e) => {
|
|
16509
16761
|
if (e instanceof NativeAuthError &&
|
|
16510
16762
|
isFatalNativeAuthError(e)) {
|
|
16511
|
-
this.
|
|
16763
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16512
16764
|
const redirectClient = this.createRedirectClient(correlationId);
|
|
16513
16765
|
return redirectClient.acquireToken(request);
|
|
16514
16766
|
}
|
|
@@ -16589,7 +16841,7 @@
|
|
|
16589
16841
|
.catch((e) => {
|
|
16590
16842
|
if (e instanceof NativeAuthError &&
|
|
16591
16843
|
isFatalNativeAuthError(e)) {
|
|
16592
|
-
this.
|
|
16844
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16593
16845
|
const popupClient = this.createPopupClient(correlationId);
|
|
16594
16846
|
return popupClient.acquireToken(request, pkce);
|
|
16595
16847
|
}
|
|
@@ -16698,7 +16950,7 @@
|
|
|
16698
16950
|
result = this.acquireTokenNative(validRequest, ApiId.ssoSilent).catch((e) => {
|
|
16699
16951
|
// If native token acquisition fails for availability reasons fallback to standard flow
|
|
16700
16952
|
if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
|
|
16701
|
-
this.
|
|
16953
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16702
16954
|
const silentIframeClient = this.createSilentIframeClient(validRequest.correlationId);
|
|
16703
16955
|
return silentIframeClient.acquireToken(validRequest);
|
|
16704
16956
|
}
|
|
@@ -16800,7 +17052,7 @@
|
|
|
16800
17052
|
// If native token acquisition fails for availability reasons fallback to standard flow
|
|
16801
17053
|
if (e instanceof NativeAuthError &&
|
|
16802
17054
|
isFatalNativeAuthError(e)) {
|
|
16803
|
-
this.
|
|
17055
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16804
17056
|
}
|
|
16805
17057
|
throw e;
|
|
16806
17058
|
});
|
|
@@ -17058,10 +17310,10 @@
|
|
|
17058
17310
|
*/
|
|
17059
17311
|
async acquireTokenNative(request, apiId, accountId, cacheLookupPolicy) {
|
|
17060
17312
|
this.logger.trace("acquireTokenNative called");
|
|
17061
|
-
if (!this.
|
|
17313
|
+
if (!this.platformAuthProvider) {
|
|
17062
17314
|
throw createBrowserAuthError(nativeConnectionNotEstablished);
|
|
17063
17315
|
}
|
|
17064
|
-
const nativeClient = new
|
|
17316
|
+
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);
|
|
17065
17317
|
return nativeClient.acquireToken(request, cacheLookupPolicy);
|
|
17066
17318
|
}
|
|
17067
17319
|
/**
|
|
@@ -17070,8 +17322,12 @@
|
|
|
17070
17322
|
*/
|
|
17071
17323
|
canUsePlatformBroker(request, accountId) {
|
|
17072
17324
|
this.logger.trace("canUsePlatformBroker called");
|
|
17073
|
-
if (!
|
|
17074
|
-
this.logger.trace("canUsePlatformBroker:
|
|
17325
|
+
if (!this.platformAuthProvider) {
|
|
17326
|
+
this.logger.trace("canUsePlatformBroker: platform broker unavilable, returning false");
|
|
17327
|
+
return false;
|
|
17328
|
+
}
|
|
17329
|
+
if (!isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, request.authenticationScheme)) {
|
|
17330
|
+
this.logger.trace("canUsePlatformBroker: isBrokerAvailable returned false, returning false");
|
|
17075
17331
|
return false;
|
|
17076
17332
|
}
|
|
17077
17333
|
if (request.prompt) {
|
|
@@ -17111,39 +17367,39 @@
|
|
|
17111
17367
|
* @param correlationId
|
|
17112
17368
|
*/
|
|
17113
17369
|
createPopupClient(correlationId) {
|
|
17114
|
-
return new PopupClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.
|
|
17370
|
+
return new PopupClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.platformAuthProvider, correlationId);
|
|
17115
17371
|
}
|
|
17116
17372
|
/**
|
|
17117
17373
|
* Returns new instance of the Redirect Interaction Client
|
|
17118
17374
|
* @param correlationId
|
|
17119
17375
|
*/
|
|
17120
17376
|
createRedirectClient(correlationId) {
|
|
17121
|
-
return new RedirectClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.
|
|
17377
|
+
return new RedirectClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.nativeInternalStorage, this.platformAuthProvider, correlationId);
|
|
17122
17378
|
}
|
|
17123
17379
|
/**
|
|
17124
17380
|
* Returns new instance of the Silent Iframe Interaction Client
|
|
17125
17381
|
* @param correlationId
|
|
17126
17382
|
*/
|
|
17127
17383
|
createSilentIframeClient(correlationId) {
|
|
17128
|
-
return new SilentIframeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.ssoSilent, this.performanceClient, this.nativeInternalStorage, this.
|
|
17384
|
+
return new SilentIframeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.ssoSilent, this.performanceClient, this.nativeInternalStorage, this.platformAuthProvider, correlationId);
|
|
17129
17385
|
}
|
|
17130
17386
|
/**
|
|
17131
17387
|
* Returns new instance of the Silent Cache Interaction Client
|
|
17132
17388
|
*/
|
|
17133
17389
|
createSilentCacheClient(correlationId) {
|
|
17134
|
-
return new SilentCacheClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.
|
|
17390
|
+
return new SilentCacheClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.platformAuthProvider, correlationId);
|
|
17135
17391
|
}
|
|
17136
17392
|
/**
|
|
17137
17393
|
* Returns new instance of the Silent Refresh Interaction Client
|
|
17138
17394
|
*/
|
|
17139
17395
|
createSilentRefreshClient(correlationId) {
|
|
17140
|
-
return new SilentRefreshClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.
|
|
17396
|
+
return new SilentRefreshClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, this.performanceClient, this.platformAuthProvider, correlationId);
|
|
17141
17397
|
}
|
|
17142
17398
|
/**
|
|
17143
17399
|
* Returns new instance of the Silent AuthCode Interaction Client
|
|
17144
17400
|
*/
|
|
17145
17401
|
createSilentAuthCodeClient(correlationId) {
|
|
17146
|
-
return new SilentAuthCodeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenByCode, this.performanceClient, this.
|
|
17402
|
+
return new SilentAuthCodeClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenByCode, this.performanceClient, this.platformAuthProvider, correlationId);
|
|
17147
17403
|
}
|
|
17148
17404
|
/**
|
|
17149
17405
|
* Adds event callbacks to array
|
|
@@ -17489,14 +17745,14 @@
|
|
|
17489
17745
|
*/
|
|
17490
17746
|
async acquireTokenSilentNoIframe(silentRequest, cacheLookupPolicy) {
|
|
17491
17747
|
// if the cache policy is set to access_token only, we should not be hitting the native layer yet
|
|
17492
|
-
if (
|
|
17748
|
+
if (isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, silentRequest.authenticationScheme) &&
|
|
17493
17749
|
silentRequest.account.nativeAccountId) {
|
|
17494
17750
|
this.logger.verbose("acquireTokenSilent - attempting to acquire token from native platform");
|
|
17495
17751
|
return this.acquireTokenNative(silentRequest, ApiId.acquireTokenSilent_silentFlow, silentRequest.account.nativeAccountId, cacheLookupPolicy).catch(async (e) => {
|
|
17496
17752
|
// If native token acquisition fails for availability reasons fallback to web flow
|
|
17497
17753
|
if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
|
|
17498
17754
|
this.logger.verbose("acquireTokenSilent - native platform unavailable, falling back to web flow");
|
|
17499
|
-
this.
|
|
17755
|
+
this.platformAuthProvider = undefined; // Prevent future requests from continuing to attempt
|
|
17500
17756
|
// Cache will not contain tokens, given that previous WAM requests succeeded. Skip cache and RT renewal and go straight to iframe renewal
|
|
17501
17757
|
throw createClientAuthError(tokenRefreshRequired);
|
|
17502
17758
|
}
|
|
@@ -17539,6 +17795,23 @@
|
|
|
17539
17795
|
this.performanceClient.addFields({ usePreGeneratedPkce: !!res }, correlationId);
|
|
17540
17796
|
return res;
|
|
17541
17797
|
}
|
|
17798
|
+
logMultipleInstances(performanceEvent) {
|
|
17799
|
+
const clientId = this.config.auth.clientId;
|
|
17800
|
+
if (!window)
|
|
17801
|
+
return;
|
|
17802
|
+
// @ts-ignore
|
|
17803
|
+
window.msal = window.msal || {};
|
|
17804
|
+
// @ts-ignore
|
|
17805
|
+
window.msal.clientIds = window.msal.clientIds || [];
|
|
17806
|
+
// @ts-ignore
|
|
17807
|
+
const clientIds = window.msal.clientIds;
|
|
17808
|
+
if (clientIds.length > 0) {
|
|
17809
|
+
this.logger.verbose("There is already an instance of MSAL.js in the window.");
|
|
17810
|
+
}
|
|
17811
|
+
// @ts-ignore
|
|
17812
|
+
window.msal.clientIds.push(clientId);
|
|
17813
|
+
collectInstanceStats(clientId, performanceEvent, this.logger);
|
|
17814
|
+
}
|
|
17542
17815
|
}
|
|
17543
17816
|
/**
|
|
17544
17817
|
* Determines whether an error thrown by the refresh token endpoint can be resolved without interaction
|
|
@@ -17825,7 +18098,9 @@
|
|
|
17825
18098
|
* Specific implementation of initialize function for NestedAppAuthController
|
|
17826
18099
|
* @returns
|
|
17827
18100
|
*/
|
|
17828
|
-
async initialize(request
|
|
18101
|
+
async initialize(request,
|
|
18102
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
18103
|
+
isBroker) {
|
|
17829
18104
|
const initCorrelationId = request?.correlationId || createNewGuid();
|
|
17830
18105
|
await this.browserStorage.initialize(initCorrelationId);
|
|
17831
18106
|
return Promise.resolve();
|
|
@@ -18347,6 +18622,7 @@
|
|
|
18347
18622
|
* @param IController Optional parameter to explictly set the controller. (Will be removed when we remove public constructor)
|
|
18348
18623
|
*/
|
|
18349
18624
|
constructor(configuration, controller) {
|
|
18625
|
+
this.isBroker = false;
|
|
18350
18626
|
this.controller =
|
|
18351
18627
|
controller ||
|
|
18352
18628
|
new StandardController(new StandardOperatingContext(configuration));
|
|
@@ -18356,7 +18632,7 @@
|
|
|
18356
18632
|
* @param request {?InitializeApplicationRequest}
|
|
18357
18633
|
*/
|
|
18358
18634
|
async initialize(request) {
|
|
18359
|
-
return this.controller.initialize(request);
|
|
18635
|
+
return this.controller.initialize(request, this.isBroker);
|
|
18360
18636
|
}
|
|
18361
18637
|
/**
|
|
18362
18638
|
* Use when you want to obtain an access_token for your API via opening a popup window in the user's browser
|
|
@@ -19859,6 +20135,7 @@
|
|
|
19859
20135
|
exports.WrapperSKU = WrapperSKU;
|
|
19860
20136
|
exports.createNestablePublicClientApplication = createNestablePublicClientApplication;
|
|
19861
20137
|
exports.createStandardPublicClientApplication = createStandardPublicClientApplication;
|
|
20138
|
+
exports.isPlatformBrokerAvailable = isPlatformBrokerAvailable;
|
|
19862
20139
|
exports.stubbedPublicClientApplication = stubbedPublicClientApplication;
|
|
19863
20140
|
exports.version = version;
|
|
19864
20141
|
|