@azure/msal-browser 4.12.0 → 4.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/IPublicClientApplication.mjs +1 -1
- package/dist/app/PublicClientApplication.mjs +1 -1
- package/dist/app/PublicClientNext.mjs +1 -1
- package/dist/broker/nativeBroker/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 +17 -2
- 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/NestedAppAuthController.mjs +1 -1
- package/dist/controllers/StandardController.d.ts +2 -2
- package/dist/controllers/StandardController.d.ts.map +1 -1
- package/dist/controllers/StandardController.mjs +30 -29
- 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 +3 -3
- package/dist/navigation/NavigationClient.mjs.map +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.mjs +1 -1
- package/lib/msal-browser.cjs +1541 -1320
- package/lib/msal-browser.cjs.map +1 -1
- package/lib/msal-browser.js +1541 -1320
- package/lib/msal-browser.js.map +1 -1
- package/lib/msal-browser.min.js +66 -66
- 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/StandardController.d.ts +2 -2
- 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/package.json +2 -2
- 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 +27 -3
- package/src/controllers/StandardController.ts +51 -45
- 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/navigation/NavigationClient.ts +2 -2
- package/src/packageMetadata.ts +1 -1
- package/src/protocol/Authorize.ts +12 -10
- package/src/utils/BrowserConstants.ts +9 -1
- 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.1 2025-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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-06-10 */
|
|
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.
|
|
@@ -10167,10 +10164,10 @@
|
|
|
10167
10164
|
*/
|
|
10168
10165
|
static defaultNavigateWindow(url, options) {
|
|
10169
10166
|
if (options.noHistory) {
|
|
10170
|
-
window.location.replace(url);
|
|
10167
|
+
window.location.replace(url); // CodeQL [SM03712] Application owner controls the URL. User can't change it.
|
|
10171
10168
|
}
|
|
10172
10169
|
else {
|
|
10173
|
-
window.location.assign(url);
|
|
10170
|
+
window.location.assign(url); // CodeQL [SM03712] Application owner controls the URL. User can't change it.
|
|
10174
10171
|
}
|
|
10175
10172
|
return new Promise((resolve) => {
|
|
10176
10173
|
setTimeout(() => {
|
|
@@ -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.1";
|
|
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.
|
|
@@ -12888,14 +12900,14 @@
|
|
|
12888
12900
|
* Licensed under the MIT License.
|
|
12889
12901
|
*/
|
|
12890
12902
|
class BaseInteractionClient {
|
|
12891
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient,
|
|
12903
|
+
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, platformAuthProvider, correlationId) {
|
|
12892
12904
|
this.config = config;
|
|
12893
12905
|
this.browserStorage = storageImpl;
|
|
12894
12906
|
this.browserCrypto = browserCrypto;
|
|
12895
12907
|
this.networkClient = this.config.system.networkClient;
|
|
12896
12908
|
this.eventHandler = eventHandler;
|
|
12897
12909
|
this.navigationClient = navigationClient;
|
|
12898
|
-
this.
|
|
12910
|
+
this.platformAuthProvider = platformAuthProvider;
|
|
12899
12911
|
this.correlationId = correlationId || createNewGuid();
|
|
12900
12912
|
this.logger = logger.clone(BrowserConstants.MSAL_SKU, version, this.correlationId);
|
|
12901
12913
|
this.performanceClient = performanceClient;
|
|
@@ -13251,6 +13263,159 @@
|
|
|
13251
13263
|
}
|
|
13252
13264
|
}
|
|
13253
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
|
+
|
|
13254
13419
|
/*
|
|
13255
13420
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13256
13421
|
* Licensed under the MIT License.
|
|
@@ -13335,930 +13500,1153 @@
|
|
|
13335
13500
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13336
13501
|
* Licensed under the MIT License.
|
|
13337
13502
|
*/
|
|
13338
|
-
class
|
|
13339
|
-
constructor(logger, handshakeTimeoutMs, performanceClient, extensionId) {
|
|
13340
|
-
this.logger = logger;
|
|
13341
|
-
this.handshakeTimeoutMs = handshakeTimeoutMs;
|
|
13342
|
-
this.extensionId = extensionId;
|
|
13343
|
-
this.resolvers = new Map(); // Used for non-handshake messages
|
|
13344
|
-
this.handshakeResolvers = new Map(); // Used for handshake messages
|
|
13345
|
-
this.messageChannel = new MessageChannel();
|
|
13346
|
-
this.windowListener = this.onWindowMessage.bind(this); // Window event callback doesn't have access to 'this' unless it's bound
|
|
13347
|
-
this.performanceClient = performanceClient;
|
|
13348
|
-
this.handshakeEvent = performanceClient.startMeasurement(PerformanceEvents.NativeMessageHandlerHandshake);
|
|
13349
|
-
}
|
|
13503
|
+
class SilentCacheClient extends StandardInteractionClient {
|
|
13350
13504
|
/**
|
|
13351
|
-
*
|
|
13352
|
-
* @param
|
|
13505
|
+
* Returns unexpired tokens from the cache, if available
|
|
13506
|
+
* @param silentRequest
|
|
13353
13507
|
*/
|
|
13354
|
-
async
|
|
13355
|
-
this.
|
|
13356
|
-
|
|
13357
|
-
|
|
13358
|
-
|
|
13359
|
-
|
|
13360
|
-
|
|
13361
|
-
|
|
13362
|
-
|
|
13363
|
-
this.logger.tracePii(`NativeMessageHandler - Sending request to browser extension: ${JSON.stringify(req)}`);
|
|
13364
|
-
this.messageChannel.port1.postMessage(req);
|
|
13365
|
-
return new Promise((resolve, reject) => {
|
|
13366
|
-
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,
|
|
13367
13517
|
});
|
|
13368
|
-
|
|
13369
|
-
|
|
13370
|
-
* Returns an instance of the MessageHandler that has successfully established a connection with an extension
|
|
13371
|
-
* @param {Logger} logger
|
|
13372
|
-
* @param {number} handshakeTimeoutMs
|
|
13373
|
-
* @param {IPerformanceClient} performanceClient
|
|
13374
|
-
* @param {ICrypto} crypto
|
|
13375
|
-
*/
|
|
13376
|
-
static async createProvider(logger, handshakeTimeoutMs, performanceClient) {
|
|
13377
|
-
logger.trace("NativeMessageHandler - createProvider called.");
|
|
13518
|
+
const silentAuthClient = new SilentFlowClient(clientConfig, this.performanceClient);
|
|
13519
|
+
this.logger.verbose("Silent auth client created");
|
|
13378
13520
|
try {
|
|
13379
|
-
const
|
|
13380
|
-
|
|
13381
|
-
|
|
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;
|
|
13382
13527
|
}
|
|
13383
|
-
catch (
|
|
13384
|
-
|
|
13385
|
-
|
|
13386
|
-
|
|
13387
|
-
|
|
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;
|
|
13388
13534
|
}
|
|
13389
13535
|
}
|
|
13390
13536
|
/**
|
|
13391
|
-
*
|
|
13537
|
+
* API to silenty clear the browser cache.
|
|
13538
|
+
* @param logoutRequest
|
|
13392
13539
|
*/
|
|
13393
|
-
|
|
13394
|
-
this.logger.
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
|
|
13398
|
-
|
|
13399
|
-
|
|
13400
|
-
|
|
13401
|
-
|
|
13402
|
-
|
|
13403
|
-
|
|
13404
|
-
|
|
13405
|
-
|
|
13406
|
-
|
|
13407
|
-
|
|
13408
|
-
|
|
13409
|
-
this.
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
|
|
13415
|
-
|
|
13416
|
-
|
|
13417
|
-
|
|
13418
|
-
* This typically suggests an event handler stopped propagation of the Handshake request but did not respond to it on the MessageChannel port
|
|
13419
|
-
*/
|
|
13420
|
-
window.removeEventListener("message", this.windowListener, false);
|
|
13421
|
-
this.messageChannel.port1.close();
|
|
13422
|
-
this.messageChannel.port2.close();
|
|
13423
|
-
this.handshakeEvent.end({
|
|
13424
|
-
extensionHandshakeTimedOut: true,
|
|
13425
|
-
success: false,
|
|
13426
|
-
});
|
|
13427
|
-
reject(createBrowserAuthError(nativeHandshakeTimeout));
|
|
13428
|
-
this.handshakeResolvers.delete(req.responseId);
|
|
13429
|
-
}, 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(),
|
|
13430
13565
|
});
|
|
13431
13566
|
}
|
|
13432
13567
|
/**
|
|
13433
|
-
*
|
|
13434
|
-
* @param
|
|
13568
|
+
* Adds SKUs to request extra query parameters
|
|
13569
|
+
* @param request {PlatformAuthRequest}
|
|
13570
|
+
* @private
|
|
13435
13571
|
*/
|
|
13436
|
-
|
|
13437
|
-
|
|
13438
|
-
|
|
13439
|
-
|
|
13440
|
-
|
|
13441
|
-
}
|
|
13442
|
-
const request = event.data;
|
|
13443
|
-
if (!request.channel ||
|
|
13444
|
-
request.channel !== NativeConstants.CHANNEL_ID) {
|
|
13445
|
-
return;
|
|
13446
|
-
}
|
|
13447
|
-
if (request.extensionId && request.extensionId !== this.extensionId) {
|
|
13448
|
-
return;
|
|
13449
|
-
}
|
|
13450
|
-
if (request.body.method === NativeExtensionMethod.HandshakeRequest) {
|
|
13451
|
-
const handshakeResolver = this.handshakeResolvers.get(request.responseId);
|
|
13452
|
-
/*
|
|
13453
|
-
* Filter out responses with no matched resolvers sooner to keep channel ports open while waiting for
|
|
13454
|
-
* the proper response.
|
|
13455
|
-
*/
|
|
13456
|
-
if (!handshakeResolver) {
|
|
13457
|
-
this.logger.trace(`NativeMessageHandler.onWindowMessage - resolver can't be found for request ${request.responseId}`);
|
|
13458
|
-
return;
|
|
13459
|
-
}
|
|
13460
|
-
// If we receive this message back it means no extension intercepted the request, meaning no extension supporting handshake protocol is installed
|
|
13461
|
-
this.logger.verbose(request.extensionId
|
|
13462
|
-
? `Extension with id: ${request.extensionId} not installed`
|
|
13463
|
-
: "No extension installed");
|
|
13464
|
-
clearTimeout(this.timeoutId);
|
|
13465
|
-
this.messageChannel.port1.close();
|
|
13466
|
-
this.messageChannel.port2.close();
|
|
13467
|
-
window.removeEventListener("message", this.windowListener, false);
|
|
13468
|
-
this.handshakeEvent.end({
|
|
13469
|
-
success: false,
|
|
13470
|
-
extensionInstalled: false,
|
|
13471
|
-
});
|
|
13472
|
-
handshakeResolver.reject(createBrowserAuthError(nativeExtensionNotInstalled));
|
|
13473
|
-
}
|
|
13572
|
+
addRequestSKUs(request) {
|
|
13573
|
+
request.extraParameters = {
|
|
13574
|
+
...request.extraParameters,
|
|
13575
|
+
[X_CLIENT_EXTRA_SKU]: this.skus,
|
|
13576
|
+
};
|
|
13474
13577
|
}
|
|
13475
13578
|
/**
|
|
13476
|
-
*
|
|
13477
|
-
* @param
|
|
13579
|
+
* Acquire token from native platform via browser extension
|
|
13580
|
+
* @param request
|
|
13478
13581
|
*/
|
|
13479
|
-
|
|
13480
|
-
this.
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
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);
|
|
13484
13589
|
try {
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
|
|
13492
|
-
|
|
13493
|
-
|
|
13494
|
-
|
|
13495
|
-
|
|
13496
|
-
else if (response.result) {
|
|
13497
|
-
if (response.result["code"] &&
|
|
13498
|
-
response.result["description"]) {
|
|
13499
|
-
resolver.reject(createNativeAuthError(response.result["code"], response.result["description"], response.result["ext"]));
|
|
13500
|
-
}
|
|
13501
|
-
else {
|
|
13502
|
-
resolver.resolve(response.result);
|
|
13503
|
-
}
|
|
13504
|
-
}
|
|
13505
|
-
else {
|
|
13506
|
-
throw createAuthError(unexpectedError, "Event does not contain result.");
|
|
13507
|
-
}
|
|
13508
|
-
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;
|
|
13509
13601
|
}
|
|
13510
|
-
|
|
13511
|
-
if (
|
|
13512
|
-
this.logger.
|
|
13513
|
-
|
|
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;
|
|
13514
13606
|
}
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
|
|
13520
|
-
|
|
13521
|
-
|
|
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({
|
|
13522
13614
|
success: true,
|
|
13615
|
+
isNativeBroker: true,
|
|
13616
|
+
requestId: result.requestId,
|
|
13523
13617
|
});
|
|
13524
|
-
|
|
13525
|
-
|
|
13526
|
-
}
|
|
13527
|
-
|
|
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
|
+
});
|
|
13528
13630
|
}
|
|
13529
|
-
catch (
|
|
13530
|
-
|
|
13531
|
-
|
|
13532
|
-
this.logger.errorPii(`Unable to parse ${event}`);
|
|
13533
|
-
if (resolver) {
|
|
13534
|
-
resolver.reject(err);
|
|
13535
|
-
}
|
|
13536
|
-
else if (handshakeResolver) {
|
|
13537
|
-
handshakeResolver.reject(err);
|
|
13631
|
+
catch (e) {
|
|
13632
|
+
if (e instanceof NativeAuthError) {
|
|
13633
|
+
serverTelemetryManager.setNativeBrokerErrorCode(e.errorCode);
|
|
13538
13634
|
}
|
|
13635
|
+
throw e;
|
|
13539
13636
|
}
|
|
13540
13637
|
}
|
|
13541
13638
|
/**
|
|
13542
|
-
*
|
|
13543
|
-
* @
|
|
13639
|
+
* Creates silent flow request
|
|
13640
|
+
* @param request
|
|
13641
|
+
* @param cachedAccount
|
|
13642
|
+
* @returns CommonSilentFlowRequest
|
|
13544
13643
|
*/
|
|
13545
|
-
|
|
13546
|
-
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
|
+
};
|
|
13547
13652
|
}
|
|
13548
13653
|
/**
|
|
13549
|
-
*
|
|
13550
|
-
* @
|
|
13654
|
+
* Fetches the tokens from the cache if un-expired
|
|
13655
|
+
* @param nativeAccountId
|
|
13656
|
+
* @param request
|
|
13657
|
+
* @returns authenticationResult
|
|
13551
13658
|
*/
|
|
13552
|
-
|
|
13553
|
-
|
|
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
|
+
}
|
|
13554
13688
|
}
|
|
13555
13689
|
/**
|
|
13556
|
-
*
|
|
13557
|
-
* @param
|
|
13558
|
-
* @param
|
|
13559
|
-
* @param nativeExtensionProvider
|
|
13560
|
-
* @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
|
|
13561
13693
|
*/
|
|
13562
|
-
|
|
13563
|
-
logger.trace("
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
if (!nativeExtensionProvider) {
|
|
13570
|
-
logger.trace("isPlatformBrokerAvailable: Platform extension provider is not initialized, returning false");
|
|
13571
|
-
// Extension is not available
|
|
13572
|
-
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);
|
|
13573
13701
|
}
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
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
|
+
}
|
|
13583
13710
|
}
|
|
13584
13711
|
}
|
|
13585
|
-
|
|
13586
|
-
|
|
13587
|
-
|
|
13588
|
-
|
|
13589
|
-
|
|
13590
|
-
|
|
13591
|
-
|
|
13592
|
-
|
|
13593
|
-
|
|
13594
|
-
|
|
13595
|
-
|
|
13596
|
-
* @param state
|
|
13597
|
-
*/
|
|
13598
|
-
function extractBrowserRequestState(browserCrypto, state) {
|
|
13599
|
-
if (!state) {
|
|
13600
|
-
return null;
|
|
13601
|
-
}
|
|
13602
|
-
try {
|
|
13603
|
-
const requestStateObj = ProtocolUtils.parseRequestState(browserCrypto, state);
|
|
13604
|
-
return requestStateObj.libraryState.meta;
|
|
13605
|
-
}
|
|
13606
|
-
catch (e) {
|
|
13607
|
-
throw createClientAuthError(invalidState);
|
|
13608
|
-
}
|
|
13609
|
-
}
|
|
13610
|
-
|
|
13611
|
-
/*
|
|
13612
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13613
|
-
* Licensed under the MIT License.
|
|
13614
|
-
*/
|
|
13615
|
-
function deserializeResponse(responseString, responseLocation, logger) {
|
|
13616
|
-
// Deserialize hash fragment response parameters.
|
|
13617
|
-
const serverParams = getDeserializedResponse(responseString);
|
|
13618
|
-
if (!serverParams) {
|
|
13619
|
-
if (!stripLeadingHashOrQuery(responseString)) {
|
|
13620
|
-
// Hash or Query string is empty
|
|
13621
|
-
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.`);
|
|
13622
|
-
throw createBrowserAuthError(hashEmptyError);
|
|
13623
|
-
}
|
|
13624
|
-
else {
|
|
13625
|
-
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.`);
|
|
13626
|
-
logger.errorPii(`The ${responseLocation} detected is: ${responseString}`);
|
|
13627
|
-
throw createBrowserAuthError(hashDoesNotContainKnownProperties);
|
|
13628
|
-
}
|
|
13629
|
-
}
|
|
13630
|
-
return serverParams;
|
|
13631
|
-
}
|
|
13632
|
-
/**
|
|
13633
|
-
* Returns the interaction type that the response object belongs to
|
|
13634
|
-
*/
|
|
13635
|
-
function validateInteractionType(response, browserCrypto, interactionType) {
|
|
13636
|
-
if (!response.state) {
|
|
13637
|
-
throw createBrowserAuthError(noStateInHash);
|
|
13638
|
-
}
|
|
13639
|
-
const platformStateObj = extractBrowserRequestState(browserCrypto, response.state);
|
|
13640
|
-
if (!platformStateObj) {
|
|
13641
|
-
throw createBrowserAuthError(unableToParseState);
|
|
13642
|
-
}
|
|
13643
|
-
if (platformStateObj.interactionType !== interactionType) {
|
|
13644
|
-
throw createBrowserAuthError(stateInteractionTypeMismatch);
|
|
13645
|
-
}
|
|
13646
|
-
}
|
|
13647
|
-
|
|
13648
|
-
/*
|
|
13649
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13650
|
-
* Licensed under the MIT License.
|
|
13651
|
-
*/
|
|
13652
|
-
/**
|
|
13653
|
-
* Abstract class which defines operations for a browser interaction handling class.
|
|
13654
|
-
*/
|
|
13655
|
-
class InteractionHandler {
|
|
13656
|
-
constructor(authCodeModule, storageImpl, authCodeRequest, logger, performanceClient) {
|
|
13657
|
-
this.authModule = authCodeModule;
|
|
13658
|
-
this.browserStorage = storageImpl;
|
|
13659
|
-
this.authCodeRequest = authCodeRequest;
|
|
13660
|
-
this.logger = logger;
|
|
13661
|
-
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
|
|
13662
13723
|
}
|
|
13663
13724
|
/**
|
|
13664
|
-
*
|
|
13665
|
-
* @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
|
|
13666
13728
|
*/
|
|
13667
|
-
async
|
|
13668
|
-
this.
|
|
13669
|
-
|
|
13670
|
-
|
|
13671
|
-
|
|
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;
|
|
13672
13734
|
}
|
|
13673
|
-
|
|
13674
|
-
|
|
13675
|
-
|
|
13676
|
-
|
|
13677
|
-
|
|
13678
|
-
|
|
13679
|
-
else {
|
|
13680
|
-
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);
|
|
13681
13741
|
}
|
|
13742
|
+
return null;
|
|
13682
13743
|
}
|
|
13683
|
-
|
|
13684
|
-
|
|
13685
|
-
|
|
13686
|
-
* Process auth code response from AAD
|
|
13687
|
-
* @param authCodeResponse
|
|
13688
|
-
* @param state
|
|
13689
|
-
* @param authority
|
|
13690
|
-
* @param networkModule
|
|
13691
|
-
* @returns
|
|
13692
|
-
*/
|
|
13693
|
-
async handleCodeResponseFromServer(authCodeResponse, request, validateNonce = true) {
|
|
13694
|
-
this.performanceClient.addQueueMeasurement(PerformanceEvents.HandleCodeResponseFromServer, request.correlationId);
|
|
13695
|
-
this.logger.trace("InteractionHandler.handleCodeResponseFromServer called");
|
|
13696
|
-
// Assign code to request
|
|
13697
|
-
this.authCodeRequest.code = authCodeResponse.code;
|
|
13698
|
-
// Check for new cloud instance
|
|
13699
|
-
if (authCodeResponse.cloud_instance_host_name) {
|
|
13700
|
-
await invokeAsync(this.authModule.updateAuthority.bind(this.authModule), PerformanceEvents.UpdateTokenEndpointAuthority, this.logger, this.performanceClient, request.correlationId)(authCodeResponse.cloud_instance_host_name, request.correlationId);
|
|
13701
|
-
}
|
|
13702
|
-
// Nonce validation not needed when redirect not involved (e.g. hybrid spa, renewing token via rt)
|
|
13703
|
-
if (validateNonce) {
|
|
13704
|
-
// TODO: Assigning "response nonce" to "request nonce" is confusing. Refactor the function doing validation to accept request nonce directly
|
|
13705
|
-
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.");
|
|
13706
13747
|
}
|
|
13707
|
-
|
|
13708
|
-
|
|
13709
|
-
|
|
13710
|
-
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;
|
|
13711
13757
|
}
|
|
13712
|
-
|
|
13713
|
-
|
|
13714
|
-
if (ccsCred) {
|
|
13715
|
-
this.authCodeRequest.ccsCredential = ccsCred;
|
|
13716
|
-
}
|
|
13758
|
+
catch (e) {
|
|
13759
|
+
throw e;
|
|
13717
13760
|
}
|
|
13718
|
-
// Acquire token with retrieved code.
|
|
13719
|
-
const tokenResponse = (await invokeAsync(this.authModule.acquireToken.bind(this.authModule), PerformanceEvents.AuthClientAcquireToken, this.logger, this.performanceClient, request.correlationId)(this.authCodeRequest, authCodeResponse));
|
|
13720
|
-
return tokenResponse;
|
|
13721
13761
|
}
|
|
13722
13762
|
/**
|
|
13723
|
-
*
|
|
13763
|
+
* Logout from native platform via browser extension
|
|
13764
|
+
* @param request
|
|
13724
13765
|
*/
|
|
13725
|
-
|
|
13726
|
-
|
|
13727
|
-
|
|
13728
|
-
credential: request.account.homeAccountId,
|
|
13729
|
-
type: CcsCredentialType.HOME_ACCOUNT_ID,
|
|
13730
|
-
};
|
|
13731
|
-
}
|
|
13732
|
-
else if (request.loginHint) {
|
|
13733
|
-
return {
|
|
13734
|
-
credential: request.loginHint,
|
|
13735
|
-
type: CcsCredentialType.UPN,
|
|
13736
|
-
};
|
|
13737
|
-
}
|
|
13738
|
-
return null;
|
|
13766
|
+
logout() {
|
|
13767
|
+
this.logger.trace("NativeInteractionClient - logout called.");
|
|
13768
|
+
return Promise.reject("Logout not implemented yet");
|
|
13739
13769
|
}
|
|
13740
|
-
}
|
|
13741
|
-
|
|
13742
|
-
/*
|
|
13743
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13744
|
-
* Licensed under the MIT License.
|
|
13745
|
-
*/
|
|
13746
|
-
class SilentCacheClient extends StandardInteractionClient {
|
|
13747
13770
|
/**
|
|
13748
|
-
*
|
|
13749
|
-
* @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
|
|
13750
13775
|
*/
|
|
13751
|
-
async
|
|
13752
|
-
this.
|
|
13753
|
-
//
|
|
13754
|
-
const
|
|
13755
|
-
const
|
|
13756
|
-
|
|
13757
|
-
|
|
13758
|
-
|
|
13759
|
-
|
|
13760
|
-
|
|
13761
|
-
|
|
13762
|
-
|
|
13763
|
-
try {
|
|
13764
|
-
const response = await invokeAsync(silentAuthClient.acquireCachedToken.bind(silentAuthClient), PerformanceEvents.SilentFlowClientAcquireCachedToken, this.logger, this.performanceClient, silentRequest.correlationId)(silentRequest);
|
|
13765
|
-
const authResponse = response[0];
|
|
13766
|
-
this.performanceClient.addFields({
|
|
13767
|
-
fromCache: true,
|
|
13768
|
-
}, silentRequest.correlationId);
|
|
13769
|
-
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");
|
|
13770
13788
|
}
|
|
13771
|
-
|
|
13772
|
-
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
}
|
|
13776
|
-
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);
|
|
13777
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;
|
|
13778
13809
|
}
|
|
13779
13810
|
/**
|
|
13780
|
-
*
|
|
13781
|
-
* @param
|
|
13811
|
+
* creates an homeAccountIdentifier for the account
|
|
13812
|
+
* @param response
|
|
13813
|
+
* @param idTokenObj
|
|
13814
|
+
* @returns
|
|
13782
13815
|
*/
|
|
13783
|
-
|
|
13784
|
-
|
|
13785
|
-
const
|
|
13786
|
-
return
|
|
13787
|
-
}
|
|
13788
|
-
}
|
|
13789
|
-
|
|
13790
|
-
/*
|
|
13791
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
13792
|
-
* Licensed under the MIT License.
|
|
13793
|
-
*/
|
|
13794
|
-
class NativeInteractionClient extends BaseInteractionClient {
|
|
13795
|
-
constructor(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, provider, accountId, nativeStorageImpl, correlationId) {
|
|
13796
|
-
super(config, browserStorage, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13797
|
-
this.apiId = apiId;
|
|
13798
|
-
this.accountId = accountId;
|
|
13799
|
-
this.nativeMessageHandler = provider;
|
|
13800
|
-
this.nativeStorageManager = nativeStorageImpl;
|
|
13801
|
-
this.silentCacheClient = new SilentCacheClient(config, this.nativeStorageManager, browserCrypto, logger, eventHandler, navigationClient, performanceClient, provider, correlationId);
|
|
13802
|
-
const extensionName = this.nativeMessageHandler.getExtensionId() ===
|
|
13803
|
-
NativeConstants.PREFERRED_EXTENSION_ID
|
|
13804
|
-
? "chrome"
|
|
13805
|
-
: this.nativeMessageHandler.getExtensionId()?.length
|
|
13806
|
-
? "unknown"
|
|
13807
|
-
: undefined;
|
|
13808
|
-
this.skus = ServerTelemetryManager.makeExtraSkuString({
|
|
13809
|
-
libraryName: BrowserConstants.MSAL_SKU,
|
|
13810
|
-
libraryVersion: version,
|
|
13811
|
-
extensionName: extensionName,
|
|
13812
|
-
extensionVersion: this.nativeMessageHandler.getExtensionVersion(),
|
|
13813
|
-
});
|
|
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;
|
|
13814
13820
|
}
|
|
13815
13821
|
/**
|
|
13816
|
-
*
|
|
13817
|
-
* @param
|
|
13818
|
-
* @
|
|
13822
|
+
* Helper to generate scopes
|
|
13823
|
+
* @param response
|
|
13824
|
+
* @param request
|
|
13825
|
+
* @returns
|
|
13819
13826
|
*/
|
|
13820
|
-
|
|
13821
|
-
|
|
13822
|
-
|
|
13823
|
-
|
|
13824
|
-
};
|
|
13827
|
+
generateScopes(requestScopes, responseScopes) {
|
|
13828
|
+
return responseScopes
|
|
13829
|
+
? ScopeSet.fromString(responseScopes)
|
|
13830
|
+
: ScopeSet.fromString(requestScopes);
|
|
13825
13831
|
}
|
|
13826
13832
|
/**
|
|
13827
|
-
*
|
|
13833
|
+
* If PoP token is requesred, records the PoP token if returned from the WAM, else generates one in the browser
|
|
13828
13834
|
* @param request
|
|
13835
|
+
* @param response
|
|
13829
13836
|
*/
|
|
13830
|
-
async
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
|
|
13834
|
-
|
|
13835
|
-
|
|
13836
|
-
|
|
13837
|
-
|
|
13838
|
-
|
|
13839
|
-
|
|
13840
|
-
|
|
13841
|
-
try {
|
|
13842
|
-
const result = await this.acquireTokensFromCache(this.accountId, nativeRequest);
|
|
13843
|
-
nativeATMeasurement.end({
|
|
13844
|
-
success: true,
|
|
13845
|
-
isNativeBroker: false,
|
|
13846
|
-
fromCache: true,
|
|
13847
|
-
});
|
|
13848
|
-
return result;
|
|
13849
|
-
}
|
|
13850
|
-
catch (e) {
|
|
13851
|
-
if (cacheLookupPolicy === CacheLookupPolicy.AccessToken) {
|
|
13852
|
-
this.logger.info("MSAL internal Cache does not contain tokens, return error as per cache policy");
|
|
13853
|
-
throw e;
|
|
13854
|
-
}
|
|
13855
|
-
// continue with a native call for any and all errors
|
|
13856
|
-
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;
|
|
13857
13848
|
}
|
|
13858
|
-
|
|
13859
|
-
|
|
13860
|
-
const
|
|
13861
|
-
|
|
13862
|
-
|
|
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,
|
|
13863
13856
|
};
|
|
13864
|
-
|
|
13865
|
-
|
|
13866
|
-
|
|
13867
|
-
|
|
13868
|
-
|
|
13869
|
-
|
|
13870
|
-
isNativeBroker: true,
|
|
13871
|
-
requestId: result.requestId,
|
|
13872
|
-
});
|
|
13873
|
-
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
13874
|
-
return result;
|
|
13875
|
-
})
|
|
13876
|
-
.catch((error) => {
|
|
13877
|
-
nativeATMeasurement.end({
|
|
13878
|
-
success: false,
|
|
13879
|
-
errorCode: error.errorCode,
|
|
13880
|
-
subErrorCode: error.subError,
|
|
13881
|
-
isNativeBroker: true,
|
|
13882
|
-
});
|
|
13883
|
-
throw error;
|
|
13884
|
-
});
|
|
13885
|
-
}
|
|
13886
|
-
catch (e) {
|
|
13887
|
-
if (e instanceof NativeAuthError) {
|
|
13888
|
-
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);
|
|
13889
13863
|
}
|
|
13890
|
-
|
|
13864
|
+
return popTokenGenerator.signPopToken(response.access_token, request.keyId, shrParameters);
|
|
13865
|
+
}
|
|
13866
|
+
else {
|
|
13867
|
+
return response.access_token;
|
|
13891
13868
|
}
|
|
13892
13869
|
}
|
|
13893
13870
|
/**
|
|
13894
|
-
*
|
|
13871
|
+
* Generates authentication result
|
|
13872
|
+
* @param response
|
|
13895
13873
|
* @param request
|
|
13896
|
-
* @param
|
|
13897
|
-
* @
|
|
13874
|
+
* @param idTokenObj
|
|
13875
|
+
* @param accountEntity
|
|
13876
|
+
* @param authority
|
|
13877
|
+
* @param reqTimestamp
|
|
13878
|
+
* @returns
|
|
13898
13879
|
*/
|
|
13899
|
-
|
|
13900
|
-
|
|
13901
|
-
|
|
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,
|
|
13902
13920
|
correlationId: this.correlationId,
|
|
13903
|
-
|
|
13904
|
-
|
|
13905
|
-
forceRefresh: false,
|
|
13921
|
+
state: response.state,
|
|
13922
|
+
fromNativeBroker: true,
|
|
13906
13923
|
};
|
|
13924
|
+
return result;
|
|
13907
13925
|
}
|
|
13908
13926
|
/**
|
|
13909
|
-
*
|
|
13910
|
-
* @param
|
|
13911
|
-
* @param request
|
|
13912
|
-
* @returns authenticationResult
|
|
13927
|
+
* cache the account entity in browser storage
|
|
13928
|
+
* @param accountEntity
|
|
13913
13929
|
*/
|
|
13914
|
-
async
|
|
13915
|
-
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
|
|
13919
|
-
|
|
13920
|
-
const account = this.browserStorage.getBaseAccountInfo({
|
|
13921
|
-
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}`);
|
|
13922
13936
|
});
|
|
13923
|
-
if (!account) {
|
|
13924
|
-
throw createClientAuthError(noAccountFound);
|
|
13925
|
-
}
|
|
13926
|
-
// leverage silent flow for cached tokens retrieval
|
|
13927
|
-
try {
|
|
13928
|
-
const silentRequest = this.createSilentCacheRequest(request, account);
|
|
13929
|
-
const result = await this.silentCacheClient.acquireToken(silentRequest);
|
|
13930
|
-
const fullAccount = {
|
|
13931
|
-
...account,
|
|
13932
|
-
idTokenClaims: result?.idTokenClaims,
|
|
13933
|
-
idToken: result?.idToken,
|
|
13934
|
-
};
|
|
13935
|
-
return {
|
|
13936
|
-
...result,
|
|
13937
|
-
account: fullAccount,
|
|
13938
|
-
};
|
|
13939
|
-
}
|
|
13940
|
-
catch (e) {
|
|
13941
|
-
throw e;
|
|
13942
|
-
}
|
|
13943
13937
|
}
|
|
13944
13938
|
/**
|
|
13945
|
-
*
|
|
13946
|
-
* @param
|
|
13947
|
-
* @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
|
|
13948
13947
|
*/
|
|
13949
|
-
|
|
13950
|
-
|
|
13951
|
-
|
|
13952
|
-
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
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,
|
|
13957
13962
|
};
|
|
13958
|
-
|
|
13959
|
-
|
|
13960
|
-
|
|
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;
|
|
13961
13976
|
}
|
|
13962
|
-
|
|
13963
|
-
|
|
13964
|
-
|
|
13965
|
-
|
|
13966
|
-
|
|
13967
|
-
|
|
13968
|
-
|
|
13969
|
-
|
|
13970
|
-
|
|
13971
|
-
|
|
13972
|
-
|
|
13973
|
-
|
|
13974
|
-
|
|
13975
|
-
|
|
13976
|
-
|
|
13977
|
-
|
|
13978
|
-
|
|
13979
|
-
|
|
13980
|
-
: this.getRedirectUri(request.redirectUri);
|
|
13981
|
-
rootMeasurement.end({ success: true });
|
|
13982
|
-
await this.navigationClient.navigateExternal(redirectUri, navigationOptions); // Need to treat this as external to ensure handleRedirectPromise is run again
|
|
13983
|
-
}
|
|
13984
|
-
/**
|
|
13985
|
-
* If the previous page called native platform for a token using redirect APIs, send the same request again and return the response
|
|
13986
|
-
* @param performanceClient {IPerformanceClient?}
|
|
13987
|
-
* @param correlationId {string?} correlation identifier
|
|
13988
|
-
*/
|
|
13989
|
-
async handleRedirectPromise(performanceClient, correlationId) {
|
|
13990
|
-
this.logger.trace("NativeInteractionClient - handleRedirectPromise called.");
|
|
13991
|
-
if (!this.browserStorage.isInteractionInProgress(true)) {
|
|
13992
|
-
this.logger.info("handleRedirectPromise called but there is no interaction in progress, returning null.");
|
|
13993
|
-
return null;
|
|
13994
|
-
}
|
|
13995
|
-
// remove prompt from the request to prevent WAM from prompting twice
|
|
13996
|
-
const cachedRequest = this.browserStorage.getCachedNativeRequest();
|
|
13997
|
-
if (!cachedRequest) {
|
|
13998
|
-
this.logger.verbose("NativeInteractionClient - handleRedirectPromise called but there is no cached request, returning null.");
|
|
13999
|
-
if (performanceClient && correlationId) {
|
|
14000
|
-
performanceClient?.addFields({ errorCode: "no_cached_request" }, correlationId);
|
|
14001
|
-
}
|
|
14002
|
-
return null;
|
|
14003
|
-
}
|
|
14004
|
-
const { prompt, ...request } = cachedRequest;
|
|
14005
|
-
if (prompt) {
|
|
14006
|
-
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.");
|
|
14007
|
-
}
|
|
14008
|
-
this.browserStorage.removeItem(this.browserStorage.generateCacheKey(TemporaryCacheKeys.NATIVE_REQUEST));
|
|
14009
|
-
const messageBody = {
|
|
14010
|
-
method: NativeExtensionMethod.GetToken,
|
|
14011
|
-
request: request,
|
|
14012
|
-
};
|
|
14013
|
-
const reqTimestamp = nowSeconds();
|
|
14014
|
-
try {
|
|
14015
|
-
this.logger.verbose("NativeInteractionClient - handleRedirectPromise sending message to native broker.");
|
|
14016
|
-
const response = await this.nativeMessageHandler.sendMessage(messageBody);
|
|
14017
|
-
this.validateNativeResponse(response);
|
|
14018
|
-
const result = this.handleNativeResponse(response, request, reqTimestamp);
|
|
14019
|
-
const res = await result;
|
|
14020
|
-
const serverTelemetryManager = this.initializeServerTelemetryManager(this.apiId);
|
|
14021
|
-
serverTelemetryManager.clearNativeBrokerErrorCode();
|
|
14022
|
-
return res;
|
|
14023
|
-
}
|
|
14024
|
-
catch (e) {
|
|
14025
|
-
throw e;
|
|
14026
|
-
}
|
|
14027
|
-
}
|
|
14028
|
-
/**
|
|
14029
|
-
* Logout from native platform via browser extension
|
|
14030
|
-
* @param request
|
|
14031
|
-
*/
|
|
14032
|
-
logout() {
|
|
14033
|
-
this.logger.trace("NativeInteractionClient - logout called.");
|
|
14034
|
-
return Promise.reject("Logout not implemented yet");
|
|
14035
|
-
}
|
|
14036
|
-
/**
|
|
14037
|
-
* Transform response from native platform into AuthenticationResult object which will be returned to the end user
|
|
14038
|
-
* @param response
|
|
14039
|
-
* @param request
|
|
14040
|
-
* @param reqTimestamp
|
|
14041
|
-
*/
|
|
14042
|
-
async handleNativeResponse(response, request, reqTimestamp) {
|
|
14043
|
-
this.logger.trace("NativeInteractionClient - handleNativeResponse called.");
|
|
14044
|
-
// generate identifiers
|
|
14045
|
-
const idTokenClaims = extractTokenClaims(response.id_token, base64Decode);
|
|
14046
|
-
const homeAccountIdentifier = this.createHomeAccountIdentifier(response, idTokenClaims);
|
|
14047
|
-
const cachedhomeAccountId = this.browserStorage.getAccountInfoFilteredBy({
|
|
14048
|
-
nativeAccountId: request.accountId,
|
|
14049
|
-
})?.homeAccountId;
|
|
14050
|
-
// add exception for double brokering, please note this is temporary and will be fortified in future
|
|
14051
|
-
if (request.extraParameters?.child_client_id &&
|
|
14052
|
-
response.account.id !== request.accountId) {
|
|
14053
|
-
this.logger.info("handleNativeServerResponse: Double broker flow detected, ignoring accountId mismatch");
|
|
14054
|
-
}
|
|
14055
|
-
else if (homeAccountIdentifier !== cachedhomeAccountId &&
|
|
14056
|
-
response.account.id !== request.accountId) {
|
|
14057
|
-
// 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
|
|
14058
|
-
throw createNativeAuthError(userSwitch);
|
|
14059
|
-
}
|
|
14060
|
-
// Get the preferred_cache domain for the given authority
|
|
14061
|
-
const authority = await this.getDiscoveredAuthority({
|
|
14062
|
-
requestAuthority: request.authority,
|
|
14063
|
-
});
|
|
14064
|
-
const baseAccount = buildAccountToCache(this.browserStorage, authority, homeAccountIdentifier, base64Decode, idTokenClaims, response.client_info, undefined, // environment
|
|
14065
|
-
idTokenClaims.tid, undefined, // auth code payload
|
|
14066
|
-
response.account.id, this.logger);
|
|
14067
|
-
// Ensure expires_in is in number format
|
|
14068
|
-
response.expires_in = Number(response.expires_in);
|
|
14069
|
-
// generate authenticationResult
|
|
14070
|
-
const result = await this.generateAuthenticationResult(response, request, idTokenClaims, baseAccount, authority.canonicalAuthority, reqTimestamp);
|
|
14071
|
-
// cache accounts and tokens in the appropriate storage
|
|
14072
|
-
await this.cacheAccount(baseAccount);
|
|
14073
|
-
await this.cacheNativeTokens(response, request, homeAccountIdentifier, idTokenClaims, response.access_token, result.tenantId, reqTimestamp);
|
|
14074
|
-
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;
|
|
14075
13995
|
}
|
|
14076
13996
|
/**
|
|
14077
|
-
*
|
|
13997
|
+
* Gets MATS telemetry from native response
|
|
14078
13998
|
* @param response
|
|
14079
|
-
* @param idTokenObj
|
|
14080
13999
|
* @returns
|
|
14081
14000
|
*/
|
|
14082
|
-
|
|
14083
|
-
|
|
14084
|
-
|
|
14085
|
-
|
|
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;
|
|
14086
14011
|
}
|
|
14087
14012
|
/**
|
|
14088
|
-
*
|
|
14013
|
+
* Returns whether or not response came from native cache
|
|
14089
14014
|
* @param response
|
|
14090
|
-
* @param request
|
|
14091
14015
|
* @returns
|
|
14092
14016
|
*/
|
|
14093
|
-
|
|
14094
|
-
|
|
14095
|
-
|
|
14096
|
-
|
|
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;
|
|
14097
14023
|
}
|
|
14098
14024
|
/**
|
|
14099
|
-
*
|
|
14025
|
+
* Translates developer provided request object into NativeRequest object
|
|
14100
14026
|
* @param request
|
|
14101
|
-
* @param response
|
|
14102
14027
|
*/
|
|
14103
|
-
async
|
|
14104
|
-
|
|
14105
|
-
|
|
14106
|
-
|
|
14107
|
-
|
|
14108
|
-
|
|
14109
|
-
|
|
14110
|
-
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
|
|
14114
|
-
|
|
14115
|
-
|
|
14116
|
-
|
|
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
|
|
14117
14064
|
const shrParameters = {
|
|
14118
|
-
resourceRequestMethod: request.resourceRequestMethod,
|
|
14119
14065
|
resourceRequestUri: request.resourceRequestUri,
|
|
14066
|
+
resourceRequestMethod: request.resourceRequestMethod,
|
|
14120
14067
|
shrClaims: request.shrClaims,
|
|
14121
14068
|
shrNonce: request.shrNonce,
|
|
14122
14069
|
};
|
|
14123
|
-
|
|
14124
|
-
|
|
14125
|
-
|
|
14126
|
-
|
|
14127
|
-
|
|
14128
|
-
|
|
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;
|
|
14129
14078
|
}
|
|
14130
|
-
|
|
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;
|
|
14131
14085
|
}
|
|
14132
|
-
|
|
14133
|
-
|
|
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);
|
|
14134
14126
|
}
|
|
14135
14127
|
}
|
|
14136
14128
|
/**
|
|
14137
|
-
*
|
|
14138
|
-
* @param
|
|
14139
|
-
* @
|
|
14140
|
-
* @param idTokenObj
|
|
14141
|
-
* @param accountEntity
|
|
14142
|
-
* @param authority
|
|
14143
|
-
* @param reqTimestamp
|
|
14144
|
-
* @returns
|
|
14129
|
+
* Handles extra broker request parameters
|
|
14130
|
+
* @param request {PlatformAuthRequest}
|
|
14131
|
+
* @private
|
|
14145
14132
|
*/
|
|
14146
|
-
|
|
14147
|
-
|
|
14148
|
-
|
|
14149
|
-
|
|
14150
|
-
|
|
14151
|
-
|
|
14152
|
-
|
|
14153
|
-
const accountProperties = response.account.properties || {};
|
|
14154
|
-
const uid = accountProperties["UID"] ||
|
|
14155
|
-
idTokenClaims.oid ||
|
|
14156
|
-
idTokenClaims.sub ||
|
|
14157
|
-
Constants.EMPTY_STRING;
|
|
14158
|
-
const tid = accountProperties["TenantId"] ||
|
|
14159
|
-
idTokenClaims.tid ||
|
|
14160
|
-
Constants.EMPTY_STRING;
|
|
14161
|
-
const accountInfo = updateAccountTenantProfileData(accountEntity.getAccountInfo(), undefined, // tenantProfile optional
|
|
14162
|
-
idTokenClaims, response.id_token);
|
|
14163
|
-
/**
|
|
14164
|
-
* In pairwise broker flows, this check prevents the broker's native account id
|
|
14165
|
-
* from being returned over the embedded app's account id.
|
|
14166
|
-
*/
|
|
14167
|
-
if (accountInfo.nativeAccountId !== response.account.id) {
|
|
14168
|
-
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;
|
|
14169
14140
|
}
|
|
14170
|
-
|
|
14171
|
-
const
|
|
14172
|
-
|
|
14173
|
-
|
|
14174
|
-
|
|
14175
|
-
|
|
14176
|
-
|
|
14177
|
-
|
|
14178
|
-
|
|
14179
|
-
|
|
14180
|
-
|
|
14181
|
-
|
|
14182
|
-
|
|
14183
|
-
|
|
14184
|
-
|
|
14185
|
-
// Request timestamp and NativeResponse expires_in are in seconds, converting to Date for AuthenticationResult
|
|
14186
|
-
expiresOn: toDateFromSeconds(reqTimestamp + response.expires_in),
|
|
14187
|
-
tokenType: tokenType,
|
|
14188
|
-
correlationId: this.correlationId,
|
|
14189
|
-
state: response.state,
|
|
14190
|
-
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,
|
|
14191
14156
|
};
|
|
14192
|
-
|
|
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;
|
|
14193
14440
|
}
|
|
14194
14441
|
/**
|
|
14195
|
-
*
|
|
14196
|
-
* @param
|
|
14442
|
+
* Sends a given message to the extension and resolves with the extension response
|
|
14443
|
+
* @param request
|
|
14197
14444
|
*/
|
|
14198
|
-
async
|
|
14199
|
-
|
|
14200
|
-
|
|
14201
|
-
|
|
14202
|
-
|
|
14203
|
-
|
|
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 });
|
|
14204
14464
|
});
|
|
14465
|
+
const validatedResponse = this.validatePlatformBrokerResponse(response);
|
|
14466
|
+
return validatedResponse;
|
|
14205
14467
|
}
|
|
14206
14468
|
/**
|
|
14207
|
-
*
|
|
14208
|
-
* @param
|
|
14209
|
-
* @param
|
|
14210
|
-
* @param
|
|
14211
|
-
* @param
|
|
14212
|
-
* @param responseAccessToken
|
|
14213
|
-
* @param tenantId
|
|
14214
|
-
* @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
|
|
14215
14474
|
*/
|
|
14216
|
-
|
|
14217
|
-
|
|
14218
|
-
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14222
|
-
|
|
14223
|
-
|
|
14224
|
-
|
|
14225
|
-
|
|
14226
|
-
|
|
14227
|
-
|
|
14228
|
-
|
|
14229
|
-
|
|
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
|
+
},
|
|
14230
14503
|
};
|
|
14231
|
-
|
|
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
|
+
});
|
|
14232
14530
|
}
|
|
14233
|
-
|
|
14234
|
-
|
|
14235
|
-
|
|
14236
|
-
|
|
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
|
+
}
|
|
14237
14643
|
}
|
|
14238
|
-
this.performanceClient.addFields({
|
|
14239
|
-
extensionId: this.nativeMessageHandler.getExtensionId(),
|
|
14240
|
-
extensionVersion: this.nativeMessageHandler.getExtensionVersion(),
|
|
14241
|
-
matsBrokerVersion: mats.broker_version,
|
|
14242
|
-
matsAccountJoinOnStart: mats.account_join_on_start,
|
|
14243
|
-
matsAccountJoinOnEnd: mats.account_join_on_end,
|
|
14244
|
-
matsDeviceJoin: mats.device_join,
|
|
14245
|
-
matsPromptBehavior: mats.prompt_behavior,
|
|
14246
|
-
matsApiErrorCode: mats.api_error_code,
|
|
14247
|
-
matsUiVisible: mats.ui_visible,
|
|
14248
|
-
matsSilentCode: mats.silent_code,
|
|
14249
|
-
matsSilentBiSubCode: mats.silent_bi_sub_code,
|
|
14250
|
-
matsSilentMessage: mats.silent_message,
|
|
14251
|
-
matsSilentStatus: mats.silent_status,
|
|
14252
|
-
matsHttpStatus: mats.http_status,
|
|
14253
|
-
matsHttpEventCount: mats.http_event_count,
|
|
14254
|
-
}, this.correlationId);
|
|
14255
|
-
return mats;
|
|
14256
14644
|
}
|
|
14257
14645
|
/**
|
|
14258
14646
|
* Validates native platform response before processing
|
|
14259
14647
|
* @param response
|
|
14260
14648
|
*/
|
|
14261
|
-
|
|
14649
|
+
validatePlatformBrokerResponse(response) {
|
|
14262
14650
|
if (response.hasOwnProperty("access_token") &&
|
|
14263
14651
|
response.hasOwnProperty("id_token") &&
|
|
14264
14652
|
response.hasOwnProperty("client_info") &&
|
|
@@ -14272,425 +14660,258 @@
|
|
|
14272
14660
|
}
|
|
14273
14661
|
}
|
|
14274
14662
|
/**
|
|
14275
|
-
*
|
|
14276
|
-
* @param response
|
|
14277
|
-
* @returns
|
|
14278
|
-
*/
|
|
14279
|
-
getMATSFromResponse(response) {
|
|
14280
|
-
if (response.properties.MATS) {
|
|
14281
|
-
try {
|
|
14282
|
-
return JSON.parse(response.properties.MATS);
|
|
14283
|
-
}
|
|
14284
|
-
catch (e) {
|
|
14285
|
-
this.logger.error("NativeInteractionClient - Error parsing MATS telemetry, returning null instead");
|
|
14286
|
-
}
|
|
14287
|
-
}
|
|
14288
|
-
return null;
|
|
14289
|
-
}
|
|
14290
|
-
/**
|
|
14291
|
-
* Returns whether or not response came from native cache
|
|
14292
|
-
* @param response
|
|
14663
|
+
* Returns the Id for the browser extension this handler is communicating with
|
|
14293
14664
|
* @returns
|
|
14294
14665
|
*/
|
|
14295
|
-
|
|
14296
|
-
|
|
14297
|
-
this.logger.verbose("NativeInteractionClient - MATS telemetry does not contain field indicating if response was served from cache. Returning false.");
|
|
14298
|
-
return false;
|
|
14299
|
-
}
|
|
14300
|
-
return !!mats.is_cached;
|
|
14301
|
-
}
|
|
14302
|
-
/**
|
|
14303
|
-
* Translates developer provided request object into NativeRequest object
|
|
14304
|
-
* @param request
|
|
14305
|
-
*/
|
|
14306
|
-
async initializeNativeRequest(request) {
|
|
14307
|
-
this.logger.trace("NativeInteractionClient - initializeNativeRequest called");
|
|
14308
|
-
const requestAuthority = request.authority || this.config.auth.authority;
|
|
14309
|
-
if (request.account) {
|
|
14310
|
-
// validate authority
|
|
14311
|
-
await this.getDiscoveredAuthority({
|
|
14312
|
-
requestAuthority,
|
|
14313
|
-
requestAzureCloudOptions: request.azureCloudOptions,
|
|
14314
|
-
account: request.account,
|
|
14315
|
-
});
|
|
14316
|
-
}
|
|
14317
|
-
const canonicalAuthority = new UrlString(requestAuthority);
|
|
14318
|
-
canonicalAuthority.validateAsUri();
|
|
14319
|
-
// 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.
|
|
14320
|
-
const { scopes, ...remainingProperties } = request;
|
|
14321
|
-
const scopeSet = new ScopeSet(scopes || []);
|
|
14322
|
-
scopeSet.appendScopes(OIDC_DEFAULT_SCOPES);
|
|
14323
|
-
const getPrompt = () => {
|
|
14324
|
-
// If request is silent, prompt is always none
|
|
14325
|
-
switch (this.apiId) {
|
|
14326
|
-
case ApiId.ssoSilent:
|
|
14327
|
-
case ApiId.acquireTokenSilent_silentFlow:
|
|
14328
|
-
this.logger.trace("initializeNativeRequest: silent request sets prompt to none");
|
|
14329
|
-
return PromptValue.NONE;
|
|
14330
|
-
}
|
|
14331
|
-
// Prompt not provided, request may proceed and native broker decides if it needs to prompt
|
|
14332
|
-
if (!request.prompt) {
|
|
14333
|
-
this.logger.trace("initializeNativeRequest: prompt was not provided");
|
|
14334
|
-
return undefined;
|
|
14335
|
-
}
|
|
14336
|
-
// If request is interactive, check if prompt provided is allowed to go directly to native broker
|
|
14337
|
-
switch (request.prompt) {
|
|
14338
|
-
case PromptValue.NONE:
|
|
14339
|
-
case PromptValue.CONSENT:
|
|
14340
|
-
case PromptValue.LOGIN:
|
|
14341
|
-
this.logger.trace("initializeNativeRequest: prompt is compatible with native flow");
|
|
14342
|
-
return request.prompt;
|
|
14343
|
-
default:
|
|
14344
|
-
this.logger.trace(`initializeNativeRequest: prompt = ${request.prompt} is not compatible with native flow`);
|
|
14345
|
-
throw createBrowserAuthError(nativePromptNotSupported);
|
|
14346
|
-
}
|
|
14347
|
-
};
|
|
14348
|
-
const validatedRequest = {
|
|
14349
|
-
...remainingProperties,
|
|
14350
|
-
accountId: this.accountId,
|
|
14351
|
-
clientId: this.config.auth.clientId,
|
|
14352
|
-
authority: canonicalAuthority.urlString,
|
|
14353
|
-
scope: scopeSet.printScopes(),
|
|
14354
|
-
redirectUri: this.getRedirectUri(request.redirectUri),
|
|
14355
|
-
prompt: getPrompt(),
|
|
14356
|
-
correlationId: this.correlationId,
|
|
14357
|
-
tokenType: request.authenticationScheme,
|
|
14358
|
-
windowTitleSubstring: document.title,
|
|
14359
|
-
extraParameters: {
|
|
14360
|
-
...request.extraQueryParameters,
|
|
14361
|
-
...request.tokenQueryParameters,
|
|
14362
|
-
},
|
|
14363
|
-
extendedExpiryToken: false,
|
|
14364
|
-
keyId: request.popKid,
|
|
14365
|
-
};
|
|
14366
|
-
// Check for PoP token requests: signPopToken should only be set to true if popKid is not set
|
|
14367
|
-
if (validatedRequest.signPopToken && !!request.popKid) {
|
|
14368
|
-
throw createBrowserAuthError(invalidPopTokenRequest);
|
|
14369
|
-
}
|
|
14370
|
-
this.handleExtraBrokerParams(validatedRequest);
|
|
14371
|
-
validatedRequest.extraParameters =
|
|
14372
|
-
validatedRequest.extraParameters || {};
|
|
14373
|
-
validatedRequest.extraParameters.telemetry =
|
|
14374
|
-
NativeConstants.MATS_TELEMETRY;
|
|
14375
|
-
if (request.authenticationScheme === AuthenticationScheme.POP) {
|
|
14376
|
-
// add POP request type
|
|
14377
|
-
const shrParameters = {
|
|
14378
|
-
resourceRequestUri: request.resourceRequestUri,
|
|
14379
|
-
resourceRequestMethod: request.resourceRequestMethod,
|
|
14380
|
-
shrClaims: request.shrClaims,
|
|
14381
|
-
shrNonce: request.shrNonce,
|
|
14382
|
-
};
|
|
14383
|
-
const popTokenGenerator = new PopTokenGenerator(this.browserCrypto);
|
|
14384
|
-
// generate reqCnf if not provided in the request
|
|
14385
|
-
let reqCnfData;
|
|
14386
|
-
if (!validatedRequest.keyId) {
|
|
14387
|
-
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, this.logger, this.performanceClient, request.correlationId)(shrParameters, this.logger);
|
|
14388
|
-
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14389
|
-
validatedRequest.keyId = generatedReqCnfData.kid;
|
|
14390
|
-
validatedRequest.signPopToken = true;
|
|
14391
|
-
}
|
|
14392
|
-
else {
|
|
14393
|
-
reqCnfData = this.browserCrypto.base64UrlEncode(JSON.stringify({ kid: validatedRequest.keyId }));
|
|
14394
|
-
validatedRequest.signPopToken = false;
|
|
14395
|
-
}
|
|
14396
|
-
// SPAs require whole string to be passed to broker
|
|
14397
|
-
validatedRequest.reqCnf = reqCnfData;
|
|
14398
|
-
}
|
|
14399
|
-
this.addRequestSKUs(validatedRequest);
|
|
14400
|
-
return validatedRequest;
|
|
14401
|
-
}
|
|
14402
|
-
/**
|
|
14403
|
-
* Handles extra broker request parameters
|
|
14404
|
-
* @param request {NativeTokenRequest}
|
|
14405
|
-
* @private
|
|
14406
|
-
*/
|
|
14407
|
-
handleExtraBrokerParams(request) {
|
|
14408
|
-
const hasExtraBrokerParams = request.extraParameters &&
|
|
14409
|
-
request.extraParameters.hasOwnProperty(BROKER_CLIENT_ID) &&
|
|
14410
|
-
request.extraParameters.hasOwnProperty(BROKER_REDIRECT_URI) &&
|
|
14411
|
-
request.extraParameters.hasOwnProperty(CLIENT_ID);
|
|
14412
|
-
if (!request.embeddedClientId && !hasExtraBrokerParams) {
|
|
14413
|
-
return;
|
|
14414
|
-
}
|
|
14415
|
-
let child_client_id = "";
|
|
14416
|
-
const child_redirect_uri = request.redirectUri;
|
|
14417
|
-
if (request.embeddedClientId) {
|
|
14418
|
-
request.redirectUri = this.config.auth.redirectUri;
|
|
14419
|
-
child_client_id = request.embeddedClientId;
|
|
14420
|
-
}
|
|
14421
|
-
else if (request.extraParameters) {
|
|
14422
|
-
request.redirectUri =
|
|
14423
|
-
request.extraParameters[BROKER_REDIRECT_URI];
|
|
14424
|
-
child_client_id =
|
|
14425
|
-
request.extraParameters[CLIENT_ID];
|
|
14426
|
-
}
|
|
14427
|
-
request.extraParameters = {
|
|
14428
|
-
child_client_id,
|
|
14429
|
-
child_redirect_uri,
|
|
14430
|
-
};
|
|
14431
|
-
this.performanceClient?.addFields({
|
|
14432
|
-
embeddedClientId: child_client_id,
|
|
14433
|
-
embeddedRedirectUri: child_redirect_uri,
|
|
14434
|
-
}, request.correlationId);
|
|
14435
|
-
}
|
|
14436
|
-
}
|
|
14437
|
-
|
|
14438
|
-
/*
|
|
14439
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14440
|
-
* Licensed under the MIT License.
|
|
14441
|
-
*/
|
|
14442
|
-
/**
|
|
14443
|
-
* Returns map of parameters that are applicable to all calls to /authorize whether using PKCE or EAR
|
|
14444
|
-
* @param config
|
|
14445
|
-
* @param authority
|
|
14446
|
-
* @param request
|
|
14447
|
-
* @param logger
|
|
14448
|
-
* @param performanceClient
|
|
14449
|
-
* @returns
|
|
14450
|
-
*/
|
|
14451
|
-
async function getStandardParameters(config, authority, request, logger, performanceClient) {
|
|
14452
|
-
const parameters = getStandardAuthorizeRequestParameters({ ...config.auth, authority: authority }, request, logger, performanceClient);
|
|
14453
|
-
addLibraryInfo(parameters, {
|
|
14454
|
-
sku: BrowserConstants.MSAL_SKU,
|
|
14455
|
-
version: version,
|
|
14456
|
-
os: "",
|
|
14457
|
-
cpu: "",
|
|
14458
|
-
});
|
|
14459
|
-
if (config.auth.protocolMode !== ProtocolMode.OIDC) {
|
|
14460
|
-
addApplicationTelemetry(parameters, config.telemetry.application);
|
|
14666
|
+
getExtensionId() {
|
|
14667
|
+
return this.extensionId;
|
|
14461
14668
|
}
|
|
14462
|
-
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
|
|
14467
|
-
|
|
14468
|
-
const popTokenGenerator = new PopTokenGenerator(cryptoOps);
|
|
14469
|
-
// req_cnf is always sent as a string for SPAs
|
|
14470
|
-
let reqCnfData;
|
|
14471
|
-
if (!request.popKid) {
|
|
14472
|
-
const generatedReqCnfData = await invokeAsync(popTokenGenerator.generateCnf.bind(popTokenGenerator), PerformanceEvents.PopTokenGenerateCnf, logger, performanceClient, request.correlationId)(request, logger);
|
|
14473
|
-
reqCnfData = generatedReqCnfData.reqCnfString;
|
|
14474
|
-
}
|
|
14475
|
-
else {
|
|
14476
|
-
reqCnfData = cryptoOps.encodeKid(request.popKid);
|
|
14477
|
-
}
|
|
14478
|
-
addPopToken(parameters, reqCnfData);
|
|
14479
|
-
}
|
|
14669
|
+
/**
|
|
14670
|
+
* Returns the version for the browser extension this handler is communicating with
|
|
14671
|
+
* @returns
|
|
14672
|
+
*/
|
|
14673
|
+
getExtensionVersion() {
|
|
14674
|
+
return this.extensionVersion;
|
|
14480
14675
|
}
|
|
14481
|
-
|
|
14482
|
-
|
|
14483
|
-
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
|
|
14487
|
-
|
|
14488
|
-
* @param request
|
|
14489
|
-
* @param logger
|
|
14490
|
-
* @param performanceClient
|
|
14491
|
-
* @returns
|
|
14492
|
-
*/
|
|
14493
|
-
async function getAuthCodeRequestUrl(config, authority, request, logger, performanceClient) {
|
|
14494
|
-
if (!request.codeChallenge) {
|
|
14495
|
-
throw createClientConfigurationError(pkceParamsMissing);
|
|
14676
|
+
getExtensionName() {
|
|
14677
|
+
return this.getExtensionId() ===
|
|
14678
|
+
PlatformAuthConstants.PREFERRED_EXTENSION_ID
|
|
14679
|
+
? "chrome"
|
|
14680
|
+
: this.getExtensionId()?.length
|
|
14681
|
+
? "unknown"
|
|
14682
|
+
: undefined;
|
|
14496
14683
|
}
|
|
14497
|
-
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
|
|
14501
|
-
|
|
14502
|
-
}
|
|
14503
|
-
/**
|
|
14504
|
-
* Gets the form that will be posted to /authorize with request parameters when using EAR
|
|
14684
|
+
}
|
|
14685
|
+
|
|
14686
|
+
/*
|
|
14687
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14688
|
+
* Licensed under the MIT License.
|
|
14505
14689
|
*/
|
|
14506
|
-
|
|
14507
|
-
|
|
14508
|
-
|
|
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;
|
|
14509
14696
|
}
|
|
14510
|
-
|
|
14511
|
-
|
|
14512
|
-
|
|
14513
|
-
|
|
14514
|
-
|
|
14515
|
-
|
|
14516
|
-
|
|
14517
|
-
|
|
14518
|
-
|
|
14519
|
-
|
|
14520
|
-
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
* @returns
|
|
14524
|
-
*/
|
|
14525
|
-
function createForm(frame, authorizeUrl, parameters) {
|
|
14526
|
-
const form = frame.createElement("form");
|
|
14527
|
-
form.method = "post";
|
|
14528
|
-
form.action = authorizeUrl;
|
|
14529
|
-
parameters.forEach((value, key) => {
|
|
14530
|
-
const param = frame.createElement("input");
|
|
14531
|
-
param.hidden = true;
|
|
14532
|
-
param.name = key;
|
|
14533
|
-
param.value = value;
|
|
14534
|
-
form.appendChild(param);
|
|
14535
|
-
});
|
|
14536
|
-
frame.body.appendChild(form);
|
|
14537
|
-
return form;
|
|
14538
|
-
}
|
|
14539
|
-
/**
|
|
14540
|
-
* Response handler when server returns accountId on the /authorize request
|
|
14541
|
-
* @param request
|
|
14542
|
-
* @param accountId
|
|
14543
|
-
* @param apiId
|
|
14544
|
-
* @param config
|
|
14545
|
-
* @param browserStorage
|
|
14546
|
-
* @param nativeStorage
|
|
14547
|
-
* @param eventHandler
|
|
14548
|
-
* @param logger
|
|
14549
|
-
* @param performanceClient
|
|
14550
|
-
* @param nativeMessageHandler
|
|
14551
|
-
* @returns
|
|
14552
|
-
*/
|
|
14553
|
-
async function handleResponsePlatformBroker(request, accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler) {
|
|
14554
|
-
if (!nativeMessageHandler) {
|
|
14555
|
-
throw createBrowserAuthError(nativeConnectionNotEstablished);
|
|
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;
|
|
14556
14710
|
}
|
|
14557
|
-
|
|
14558
|
-
|
|
14559
|
-
|
|
14560
|
-
|
|
14561
|
-
|
|
14562
|
-
|
|
14563
|
-
prompt: undefined, // Server should handle the prompt, ideally native broker can do this part silently
|
|
14564
|
-
});
|
|
14565
|
-
}
|
|
14566
|
-
/**
|
|
14567
|
-
* Response handler when server returns code on the /authorize request
|
|
14568
|
-
* @param request
|
|
14569
|
-
* @param response
|
|
14570
|
-
* @param codeVerifier
|
|
14571
|
-
* @param authClient
|
|
14572
|
-
* @param browserStorage
|
|
14573
|
-
* @param logger
|
|
14574
|
-
* @param performanceClient
|
|
14575
|
-
* @returns
|
|
14576
|
-
*/
|
|
14577
|
-
async function handleResponseCode(request, response, codeVerifier, apiId, config, authClient, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler) {
|
|
14578
|
-
// Remove throttle if it exists
|
|
14579
|
-
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14580
|
-
if (response.accountId) {
|
|
14581
|
-
return invokeAsync(handleResponsePlatformBroker, PerformanceEvents.HandleResponsePlatformBroker, logger, performanceClient, request.correlationId)(request, response.accountId, apiId, config, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler);
|
|
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;
|
|
14582
14717
|
}
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
code: response.code || "",
|
|
14586
|
-
codeVerifier: codeVerifier,
|
|
14587
|
-
};
|
|
14588
|
-
// Create popup interaction handler.
|
|
14589
|
-
const interactionHandler = new InteractionHandler(authClient, browserStorage, authCodeRequest, logger, performanceClient);
|
|
14590
|
-
// Handle response from hash string.
|
|
14591
|
-
const result = await invokeAsync(interactionHandler.handleCodeResponse.bind(interactionHandler), PerformanceEvents.HandleCodeResponse, logger, performanceClient, request.correlationId)(response, request);
|
|
14592
|
-
return result;
|
|
14593
|
-
}
|
|
14594
|
-
/**
|
|
14595
|
-
* Response handler when server returns ear_jwe on the /authorize request
|
|
14596
|
-
* @param request
|
|
14597
|
-
* @param response
|
|
14598
|
-
* @param apiId
|
|
14599
|
-
* @param config
|
|
14600
|
-
* @param authority
|
|
14601
|
-
* @param browserStorage
|
|
14602
|
-
* @param nativeStorage
|
|
14603
|
-
* @param eventHandler
|
|
14604
|
-
* @param logger
|
|
14605
|
-
* @param performanceClient
|
|
14606
|
-
* @param nativeMessageHandler
|
|
14607
|
-
* @returns
|
|
14608
|
-
*/
|
|
14609
|
-
async function handleResponseEAR(request, response, apiId, config, authority, browserStorage, nativeStorage, eventHandler, logger, performanceClient, nativeMessageHandler) {
|
|
14610
|
-
// Remove throttle if it exists
|
|
14611
|
-
ThrottlingUtils.removeThrottle(browserStorage, config.auth.clientId, request);
|
|
14612
|
-
// Validate state & check response for errors
|
|
14613
|
-
validateAuthorizationResponse(response, request.state);
|
|
14614
|
-
if (!response.ear_jwe) {
|
|
14615
|
-
throw createBrowserAuthError(earJweEmpty);
|
|
14718
|
+
getExtensionVersion() {
|
|
14719
|
+
return "";
|
|
14616
14720
|
}
|
|
14617
|
-
|
|
14618
|
-
|
|
14721
|
+
getExtensionName() {
|
|
14722
|
+
return PlatformAuthConstants.DOM_API_NAME;
|
|
14619
14723
|
}
|
|
14620
|
-
|
|
14621
|
-
|
|
14622
|
-
|
|
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;
|
|
14623
14818
|
}
|
|
14624
|
-
const responseHandler = new ResponseHandler(config.auth.clientId, browserStorage, new CryptoOps(logger, performanceClient), logger, null, null, performanceClient);
|
|
14625
|
-
// Validate response. This function throws a server error if an error is returned by the server.
|
|
14626
|
-
responseHandler.validateTokenResponse(decryptedData);
|
|
14627
|
-
// Temporary until response handler is refactored to be more flow agnostic.
|
|
14628
|
-
const additionalData = {
|
|
14629
|
-
code: "",
|
|
14630
|
-
state: request.state,
|
|
14631
|
-
nonce: request.nonce,
|
|
14632
|
-
client_info: decryptedData.client_info,
|
|
14633
|
-
cloud_graph_host_name: decryptedData.cloud_graph_host_name,
|
|
14634
|
-
cloud_instance_host_name: decryptedData.cloud_instance_host_name,
|
|
14635
|
-
cloud_instance_name: decryptedData.cloud_instance_name,
|
|
14636
|
-
msgraph_host: decryptedData.msgraph_host,
|
|
14637
|
-
};
|
|
14638
|
-
return (await invokeAsync(responseHandler.handleServerTokenResponse.bind(responseHandler), PerformanceEvents.HandleServerTokenResponse, logger, performanceClient, request.correlationId)(decryptedData, authority, nowSeconds(), request, additionalData, undefined, undefined, undefined, undefined));
|
|
14639
14819
|
}
|
|
14640
14820
|
|
|
14641
14821
|
/*
|
|
14642
14822
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
14643
14823
|
* Licensed under the MIT License.
|
|
14644
14824
|
*/
|
|
14645
|
-
// Constant byte array length
|
|
14646
|
-
const RANDOM_BYTE_ARR_LENGTH = 32;
|
|
14647
|
-
/**
|
|
14648
|
-
* This file defines APIs to generate PKCE codes and code verifiers.
|
|
14649
|
-
*/
|
|
14650
14825
|
/**
|
|
14651
|
-
*
|
|
14826
|
+
* Checks if the platform broker is available in the current environment.
|
|
14827
|
+
* @param loggerOptions
|
|
14828
|
+
* @param perfClient
|
|
14829
|
+
* @returns
|
|
14652
14830
|
*/
|
|
14653
|
-
async function
|
|
14654
|
-
|
|
14655
|
-
|
|
14656
|
-
const
|
|
14657
|
-
|
|
14658
|
-
|
|
14659
|
-
|
|
14660
|
-
}
|
|
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()));
|
|
14661
14840
|
}
|
|
14662
|
-
|
|
14663
|
-
|
|
14664
|
-
|
|
14665
|
-
|
|
14666
|
-
|
|
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;
|
|
14667
14847
|
try {
|
|
14668
|
-
|
|
14669
|
-
|
|
14670
|
-
|
|
14671
|
-
|
|
14672
|
-
|
|
14673
|
-
|
|
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
|
+
}
|
|
14674
14862
|
}
|
|
14675
14863
|
catch (e) {
|
|
14676
|
-
|
|
14864
|
+
logger.trace("Platform auth not available", e);
|
|
14677
14865
|
}
|
|
14866
|
+
return platformAuthProvider;
|
|
14678
14867
|
}
|
|
14679
14868
|
/**
|
|
14680
|
-
*
|
|
14681
|
-
*
|
|
14869
|
+
* Returns true if the DOM API support for platform auth is enabled in session storage
|
|
14870
|
+
* @returns boolean
|
|
14871
|
+
* @deprecated
|
|
14682
14872
|
*/
|
|
14683
|
-
|
|
14684
|
-
|
|
14873
|
+
function isDomEnabledForPlatformAuth() {
|
|
14874
|
+
let sessionStorage;
|
|
14685
14875
|
try {
|
|
14686
|
-
|
|
14687
|
-
|
|
14688
|
-
|
|
14689
|
-
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";
|
|
14690
14879
|
}
|
|
14691
14880
|
catch (e) {
|
|
14692
|
-
|
|
14881
|
+
return false;
|
|
14693
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
|
+
}
|
|
14913
|
+
}
|
|
14914
|
+
return true;
|
|
14694
14915
|
}
|
|
14695
14916
|
|
|
14696
14917
|
/*
|
|
@@ -14698,8 +14919,8 @@
|
|
|
14698
14919
|
* Licensed under the MIT License.
|
|
14699
14920
|
*/
|
|
14700
14921
|
class PopupClient extends StandardInteractionClient {
|
|
14701
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl,
|
|
14702
|
-
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);
|
|
14703
14924
|
// Properly sets this reference for the unload event.
|
|
14704
14925
|
this.unloadWindow = this.unloadWindow.bind(this);
|
|
14705
14926
|
this.nativeStorage = nativeStorageImpl;
|
|
@@ -14787,7 +15008,7 @@
|
|
|
14787
15008
|
if (popupParams.popup) {
|
|
14788
15009
|
preconnect(validRequest.authority);
|
|
14789
15010
|
}
|
|
14790
|
-
const isPlatformBroker =
|
|
15011
|
+
const isPlatformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, request.authenticationScheme);
|
|
14791
15012
|
validRequest.platformBroker = isPlatformBroker;
|
|
14792
15013
|
if (this.config.auth.protocolMode === ProtocolMode.EAR) {
|
|
14793
15014
|
return this.executeEarFlow(validRequest, popupParams);
|
|
@@ -14829,7 +15050,7 @@
|
|
|
14829
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.
|
|
14830
15051
|
const responseString = await this.monitorPopupForHash(popupWindow, popupParams.popupWindowParent);
|
|
14831
15052
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.serverResponseType, this.logger);
|
|
14832
|
-
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);
|
|
14833
15054
|
}
|
|
14834
15055
|
catch (e) {
|
|
14835
15056
|
// Close the synchronous popup if an error is thrown before the window unload event is registered
|
|
@@ -14865,7 +15086,7 @@
|
|
|
14865
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.
|
|
14866
15087
|
const responseString = await invokeAsync(this.monitorPopupForHash.bind(this), PerformanceEvents.SilentHandlerMonitorIframeForHash, this.logger, this.performanceClient, correlationId)(popupWindow, popupParams.popupWindowParent);
|
|
14867
15088
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.serverResponseType, this.logger);
|
|
14868
|
-
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);
|
|
14869
15090
|
}
|
|
14870
15091
|
/**
|
|
14871
15092
|
*
|
|
@@ -15162,8 +15383,8 @@
|
|
|
15162
15383
|
return navigation?.type;
|
|
15163
15384
|
}
|
|
15164
15385
|
class RedirectClient extends StandardInteractionClient {
|
|
15165
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl,
|
|
15166
|
-
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);
|
|
15167
15388
|
this.nativeStorage = nativeStorageImpl;
|
|
15168
15389
|
}
|
|
15169
15390
|
/**
|
|
@@ -15172,8 +15393,7 @@
|
|
|
15172
15393
|
*/
|
|
15173
15394
|
async acquireToken(request) {
|
|
15174
15395
|
const validRequest = await invokeAsync(this.initializeAuthorizationRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(request, exports.InteractionType.Redirect);
|
|
15175
|
-
validRequest.platformBroker =
|
|
15176
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeMessageHandler, request.authenticationScheme);
|
|
15396
|
+
validRequest.platformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, request.authenticationScheme);
|
|
15177
15397
|
const handleBackButton = (event) => {
|
|
15178
15398
|
// Clear temporary cache if the back button is clicked during the redirect flow.
|
|
15179
15399
|
if (event.persisted) {
|
|
@@ -15413,10 +15633,10 @@
|
|
|
15413
15633
|
requestExtraQueryParameters: request.extraQueryParameters,
|
|
15414
15634
|
account: request.account,
|
|
15415
15635
|
});
|
|
15416
|
-
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);
|
|
15417
15637
|
}
|
|
15418
15638
|
const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), PerformanceEvents.StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)({ serverTelemetryManager, requestAuthority: request.authority });
|
|
15419
|
-
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);
|
|
15420
15640
|
}
|
|
15421
15641
|
/**
|
|
15422
15642
|
* Redirects window to given URL.
|
|
@@ -15700,8 +15920,8 @@
|
|
|
15700
15920
|
* Licensed under the MIT License.
|
|
15701
15921
|
*/
|
|
15702
15922
|
class SilentIframeClient extends StandardInteractionClient {
|
|
15703
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient, nativeStorageImpl,
|
|
15704
|
-
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);
|
|
15705
15925
|
this.apiId = apiId;
|
|
15706
15926
|
this.nativeStorage = nativeStorageImpl;
|
|
15707
15927
|
}
|
|
@@ -15731,8 +15951,7 @@
|
|
|
15731
15951
|
}
|
|
15732
15952
|
// Create silent request
|
|
15733
15953
|
const silentRequest = await invokeAsync(this.initializeAuthorizationRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, request.correlationId)(inputRequest, exports.InteractionType.Silent);
|
|
15734
|
-
silentRequest.platformBroker =
|
|
15735
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeMessageHandler, silentRequest.authenticationScheme);
|
|
15954
|
+
silentRequest.platformBroker = isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, silentRequest.authenticationScheme);
|
|
15736
15955
|
preconnect(silentRequest.authority);
|
|
15737
15956
|
if (this.config.auth.protocolMode === ProtocolMode.EAR) {
|
|
15738
15957
|
return this.executeEarFlow(silentRequest);
|
|
@@ -15798,7 +16017,7 @@
|
|
|
15798
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.
|
|
15799
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);
|
|
15800
16019
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, correlationId)(responseString, responseType, this.logger);
|
|
15801
|
-
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);
|
|
15802
16021
|
}
|
|
15803
16022
|
/**
|
|
15804
16023
|
* Currently Unsupported
|
|
@@ -15829,7 +16048,7 @@
|
|
|
15829
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.
|
|
15830
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);
|
|
15831
16050
|
const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, correlationId)(responseString, responseType, this.logger);
|
|
15832
|
-
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);
|
|
15833
16052
|
}
|
|
15834
16053
|
}
|
|
15835
16054
|
|
|
@@ -16110,8 +16329,8 @@
|
|
|
16110
16329
|
* Licensed under the MIT License.
|
|
16111
16330
|
*/
|
|
16112
16331
|
class SilentAuthCodeClient extends StandardInteractionClient {
|
|
16113
|
-
constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, apiId, performanceClient,
|
|
16114
|
-
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);
|
|
16115
16334
|
this.apiId = apiId;
|
|
16116
16335
|
}
|
|
16117
16336
|
/**
|
|
@@ -16325,8 +16544,8 @@
|
|
|
16325
16544
|
await invokeAsync(this.browserStorage.initialize.bind(this.browserStorage), PerformanceEvents.InitializeCache, this.logger, this.performanceClient, initCorrelationId)(initCorrelationId);
|
|
16326
16545
|
if (allowPlatformBroker) {
|
|
16327
16546
|
try {
|
|
16328
|
-
|
|
16329
|
-
|
|
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);
|
|
16330
16549
|
}
|
|
16331
16550
|
catch (e) {
|
|
16332
16551
|
this.logger.verbose(e);
|
|
@@ -16396,18 +16615,15 @@
|
|
|
16396
16615
|
}
|
|
16397
16616
|
const loggedInAccounts = this.getAllAccounts();
|
|
16398
16617
|
const platformBrokerRequest = this.browserStorage.getCachedNativeRequest();
|
|
16399
|
-
const useNative = platformBrokerRequest &&
|
|
16400
|
-
NativeMessageHandler.isPlatformBrokerAvailable(this.config, this.logger, this.nativeExtensionProvider) &&
|
|
16401
|
-
this.nativeExtensionProvider &&
|
|
16402
|
-
!hash;
|
|
16618
|
+
const useNative = platformBrokerRequest && this.platformAuthProvider && !hash;
|
|
16403
16619
|
let rootMeasurement;
|
|
16404
16620
|
this.eventHandler.emitEvent(EventType.HANDLE_REDIRECT_START, exports.InteractionType.Redirect);
|
|
16405
16621
|
let redirectResponse;
|
|
16406
16622
|
try {
|
|
16407
|
-
if (useNative && this.
|
|
16623
|
+
if (useNative && this.platformAuthProvider) {
|
|
16408
16624
|
rootMeasurement = this.performanceClient.startMeasurement(PerformanceEvents.AcquireTokenRedirect, platformBrokerRequest?.correlationId || "");
|
|
16409
16625
|
this.logger.trace("handleRedirectPromise - acquiring token from native platform");
|
|
16410
|
-
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);
|
|
16411
16627
|
redirectResponse = invokeAsync(nativeClient.handleRedirectPromise.bind(nativeClient), PerformanceEvents.HandleNativeRedirectPromiseMeasurement, this.logger, this.performanceClient, rootMeasurement.event.correlationId)(this.performanceClient, rootMeasurement.event.correlationId);
|
|
16412
16628
|
}
|
|
16413
16629
|
else {
|
|
@@ -16536,15 +16752,15 @@
|
|
|
16536
16752
|
this.eventHandler.emitEvent(EventType.LOGIN_START, exports.InteractionType.Redirect, request);
|
|
16537
16753
|
}
|
|
16538
16754
|
let result;
|
|
16539
|
-
if (this.
|
|
16755
|
+
if (this.platformAuthProvider &&
|
|
16540
16756
|
this.canUsePlatformBroker(request)) {
|
|
16541
|
-
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);
|
|
16542
16758
|
result = nativeClient
|
|
16543
16759
|
.acquireTokenRedirect(request, atrMeasurement)
|
|
16544
16760
|
.catch((e) => {
|
|
16545
16761
|
if (e instanceof NativeAuthError &&
|
|
16546
16762
|
isFatalNativeAuthError(e)) {
|
|
16547
|
-
this.
|
|
16763
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16548
16764
|
const redirectClient = this.createRedirectClient(correlationId);
|
|
16549
16765
|
return redirectClient.acquireToken(request);
|
|
16550
16766
|
}
|
|
@@ -16625,7 +16841,7 @@
|
|
|
16625
16841
|
.catch((e) => {
|
|
16626
16842
|
if (e instanceof NativeAuthError &&
|
|
16627
16843
|
isFatalNativeAuthError(e)) {
|
|
16628
|
-
this.
|
|
16844
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16629
16845
|
const popupClient = this.createPopupClient(correlationId);
|
|
16630
16846
|
return popupClient.acquireToken(request, pkce);
|
|
16631
16847
|
}
|
|
@@ -16734,7 +16950,7 @@
|
|
|
16734
16950
|
result = this.acquireTokenNative(validRequest, ApiId.ssoSilent).catch((e) => {
|
|
16735
16951
|
// If native token acquisition fails for availability reasons fallback to standard flow
|
|
16736
16952
|
if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
|
|
16737
|
-
this.
|
|
16953
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16738
16954
|
const silentIframeClient = this.createSilentIframeClient(validRequest.correlationId);
|
|
16739
16955
|
return silentIframeClient.acquireToken(validRequest);
|
|
16740
16956
|
}
|
|
@@ -16836,7 +17052,7 @@
|
|
|
16836
17052
|
// If native token acquisition fails for availability reasons fallback to standard flow
|
|
16837
17053
|
if (e instanceof NativeAuthError &&
|
|
16838
17054
|
isFatalNativeAuthError(e)) {
|
|
16839
|
-
this.
|
|
17055
|
+
this.platformAuthProvider = undefined; // If extension gets uninstalled during session prevent future requests from continuing to attempt
|
|
16840
17056
|
}
|
|
16841
17057
|
throw e;
|
|
16842
17058
|
});
|
|
@@ -17094,10 +17310,10 @@
|
|
|
17094
17310
|
*/
|
|
17095
17311
|
async acquireTokenNative(request, apiId, accountId, cacheLookupPolicy) {
|
|
17096
17312
|
this.logger.trace("acquireTokenNative called");
|
|
17097
|
-
if (!this.
|
|
17313
|
+
if (!this.platformAuthProvider) {
|
|
17098
17314
|
throw createBrowserAuthError(nativeConnectionNotEstablished);
|
|
17099
17315
|
}
|
|
17100
|
-
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);
|
|
17101
17317
|
return nativeClient.acquireToken(request, cacheLookupPolicy);
|
|
17102
17318
|
}
|
|
17103
17319
|
/**
|
|
@@ -17106,8 +17322,12 @@
|
|
|
17106
17322
|
*/
|
|
17107
17323
|
canUsePlatformBroker(request, accountId) {
|
|
17108
17324
|
this.logger.trace("canUsePlatformBroker called");
|
|
17109
|
-
if (!
|
|
17110
|
-
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");
|
|
17111
17331
|
return false;
|
|
17112
17332
|
}
|
|
17113
17333
|
if (request.prompt) {
|
|
@@ -17147,39 +17367,39 @@
|
|
|
17147
17367
|
* @param correlationId
|
|
17148
17368
|
*/
|
|
17149
17369
|
createPopupClient(correlationId) {
|
|
17150
|
-
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);
|
|
17151
17371
|
}
|
|
17152
17372
|
/**
|
|
17153
17373
|
* Returns new instance of the Redirect Interaction Client
|
|
17154
17374
|
* @param correlationId
|
|
17155
17375
|
*/
|
|
17156
17376
|
createRedirectClient(correlationId) {
|
|
17157
|
-
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);
|
|
17158
17378
|
}
|
|
17159
17379
|
/**
|
|
17160
17380
|
* Returns new instance of the Silent Iframe Interaction Client
|
|
17161
17381
|
* @param correlationId
|
|
17162
17382
|
*/
|
|
17163
17383
|
createSilentIframeClient(correlationId) {
|
|
17164
|
-
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);
|
|
17165
17385
|
}
|
|
17166
17386
|
/**
|
|
17167
17387
|
* Returns new instance of the Silent Cache Interaction Client
|
|
17168
17388
|
*/
|
|
17169
17389
|
createSilentCacheClient(correlationId) {
|
|
17170
|
-
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);
|
|
17171
17391
|
}
|
|
17172
17392
|
/**
|
|
17173
17393
|
* Returns new instance of the Silent Refresh Interaction Client
|
|
17174
17394
|
*/
|
|
17175
17395
|
createSilentRefreshClient(correlationId) {
|
|
17176
|
-
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);
|
|
17177
17397
|
}
|
|
17178
17398
|
/**
|
|
17179
17399
|
* Returns new instance of the Silent AuthCode Interaction Client
|
|
17180
17400
|
*/
|
|
17181
17401
|
createSilentAuthCodeClient(correlationId) {
|
|
17182
|
-
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);
|
|
17183
17403
|
}
|
|
17184
17404
|
/**
|
|
17185
17405
|
* Adds event callbacks to array
|
|
@@ -17525,14 +17745,14 @@
|
|
|
17525
17745
|
*/
|
|
17526
17746
|
async acquireTokenSilentNoIframe(silentRequest, cacheLookupPolicy) {
|
|
17527
17747
|
// if the cache policy is set to access_token only, we should not be hitting the native layer yet
|
|
17528
|
-
if (
|
|
17748
|
+
if (isPlatformAuthAllowed(this.config, this.logger, this.platformAuthProvider, silentRequest.authenticationScheme) &&
|
|
17529
17749
|
silentRequest.account.nativeAccountId) {
|
|
17530
17750
|
this.logger.verbose("acquireTokenSilent - attempting to acquire token from native platform");
|
|
17531
17751
|
return this.acquireTokenNative(silentRequest, ApiId.acquireTokenSilent_silentFlow, silentRequest.account.nativeAccountId, cacheLookupPolicy).catch(async (e) => {
|
|
17532
17752
|
// If native token acquisition fails for availability reasons fallback to web flow
|
|
17533
17753
|
if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
|
|
17534
17754
|
this.logger.verbose("acquireTokenSilent - native platform unavailable, falling back to web flow");
|
|
17535
|
-
this.
|
|
17755
|
+
this.platformAuthProvider = undefined; // Prevent future requests from continuing to attempt
|
|
17536
17756
|
// Cache will not contain tokens, given that previous WAM requests succeeded. Skip cache and RT renewal and go straight to iframe renewal
|
|
17537
17757
|
throw createClientAuthError(tokenRefreshRequired);
|
|
17538
17758
|
}
|
|
@@ -19915,6 +20135,7 @@
|
|
|
19915
20135
|
exports.WrapperSKU = WrapperSKU;
|
|
19916
20136
|
exports.createNestablePublicClientApplication = createNestablePublicClientApplication;
|
|
19917
20137
|
exports.createStandardPublicClientApplication = createStandardPublicClientApplication;
|
|
20138
|
+
exports.isPlatformBrokerAvailable = isPlatformBrokerAvailable;
|
|
19918
20139
|
exports.stubbedPublicClientApplication = stubbedPublicClientApplication;
|
|
19919
20140
|
exports.version = version;
|
|
19920
20141
|
|