@azure/msal-browser 3.5.1-beta.1 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/dist/app/IPublicClientApplication.d.ts +51 -51
  2. package/dist/app/IPublicClientApplication.mjs +102 -102
  3. package/dist/app/IPublicClientApplication.mjs.map +1 -1
  4. package/dist/app/PublicClientApplication.d.ts +269 -268
  5. package/dist/app/PublicClientApplication.d.ts.map +1 -1
  6. package/dist/app/PublicClientApplication.mjs +333 -333
  7. package/dist/app/PublicClientApplication.mjs.map +1 -1
  8. package/dist/app/PublicClientNext.d.ts +273 -273
  9. package/dist/app/PublicClientNext.mjs +351 -351
  10. package/dist/app/PublicClientNext.mjs.map +1 -1
  11. package/dist/broker/nativeBroker/NativeMessageHandler.d.ts +62 -62
  12. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +254 -254
  13. package/dist/broker/nativeBroker/NativeMessageHandler.mjs.map +1 -1
  14. package/dist/broker/nativeBroker/NativeRequest.d.ts +44 -44
  15. package/dist/broker/nativeBroker/NativeResponse.d.ts +48 -48
  16. package/dist/broker/nativeBroker/NativeStatusCodes.d.ts +7 -7
  17. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +11 -11
  18. package/dist/broker/nativeBroker/NativeStatusCodes.mjs.map +1 -1
  19. package/dist/cache/AsyncMemoryStorage.d.ts +51 -51
  20. package/dist/cache/AsyncMemoryStorage.mjs +132 -132
  21. package/dist/cache/AsyncMemoryStorage.mjs.map +1 -1
  22. package/dist/cache/BrowserCacheManager.d.ts +395 -383
  23. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  24. package/dist/cache/BrowserCacheManager.mjs +1282 -1262
  25. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  26. package/dist/cache/BrowserStorage.d.ts +11 -11
  27. package/dist/cache/BrowserStorage.mjs +32 -32
  28. package/dist/cache/BrowserStorage.mjs.map +1 -1
  29. package/dist/cache/CryptoKeyStore.d.ts +18 -18
  30. package/dist/cache/CryptoKeyStore.mjs +40 -40
  31. package/dist/cache/CryptoKeyStore.mjs.map +1 -1
  32. package/dist/cache/DatabaseStorage.d.ts +56 -56
  33. package/dist/cache/DatabaseStorage.mjs +190 -190
  34. package/dist/cache/DatabaseStorage.mjs.map +1 -1
  35. package/dist/cache/IAsyncMemoryStorage.d.ts +27 -27
  36. package/dist/cache/ITokenCache.d.ts +11 -11
  37. package/dist/cache/IWindowStorage.d.ts +27 -27
  38. package/dist/cache/MemoryStorage.d.ts +11 -11
  39. package/dist/cache/MemoryStorage.mjs +31 -31
  40. package/dist/cache/MemoryStorage.mjs.map +1 -1
  41. package/dist/cache/TokenCache.d.ts +77 -77
  42. package/dist/cache/TokenCache.d.ts.map +1 -1
  43. package/dist/cache/TokenCache.mjs +221 -225
  44. package/dist/cache/TokenCache.mjs.map +1 -1
  45. package/dist/config/Configuration.d.ts +206 -206
  46. package/dist/config/Configuration.d.ts.map +1 -1
  47. package/dist/config/Configuration.mjs +128 -128
  48. package/dist/config/Configuration.mjs.map +1 -1
  49. package/dist/controllers/ControllerFactory.d.ts +4 -4
  50. package/dist/controllers/ControllerFactory.d.ts.map +1 -1
  51. package/dist/controllers/ControllerFactory.mjs +29 -29
  52. package/dist/controllers/ControllerFactory.mjs.map +1 -1
  53. package/dist/controllers/IController.d.ts +61 -61
  54. package/dist/controllers/NestedAppAuthController.d.ts +95 -95
  55. package/dist/controllers/NestedAppAuthController.mjs +334 -334
  56. package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
  57. package/dist/controllers/StandardController.d.ts +407 -407
  58. package/dist/controllers/StandardController.d.ts.map +1 -1
  59. package/dist/controllers/StandardController.mjs +1291 -1293
  60. package/dist/controllers/StandardController.mjs.map +1 -1
  61. package/dist/controllers/UnknownOperatingContextController.d.ts +87 -87
  62. package/dist/controllers/UnknownOperatingContextController.mjs +264 -264
  63. package/dist/controllers/UnknownOperatingContextController.mjs.map +1 -1
  64. package/dist/crypto/BrowserCrypto.d.ts +44 -44
  65. package/dist/crypto/BrowserCrypto.mjs +93 -93
  66. package/dist/crypto/BrowserCrypto.mjs.map +1 -1
  67. package/dist/crypto/CryptoOps.d.ts +63 -63
  68. package/dist/crypto/CryptoOps.mjs +145 -145
  69. package/dist/crypto/CryptoOps.mjs.map +1 -1
  70. package/dist/crypto/PkceGenerator.d.ts +8 -8
  71. package/dist/crypto/PkceGenerator.mjs +54 -54
  72. package/dist/crypto/PkceGenerator.mjs.map +1 -1
  73. package/dist/crypto/SignedHttpRequest.d.ts +30 -30
  74. package/dist/crypto/SignedHttpRequest.mjs +39 -39
  75. package/dist/crypto/SignedHttpRequest.mjs.map +1 -1
  76. package/dist/encode/Base64Decode.d.ts +9 -9
  77. package/dist/encode/Base64Decode.mjs +36 -36
  78. package/dist/encode/Base64Decode.mjs.map +1 -1
  79. package/dist/encode/Base64Encode.d.ts +19 -19
  80. package/dist/encode/Base64Encode.mjs +43 -43
  81. package/dist/encode/Base64Encode.mjs.map +1 -1
  82. package/dist/error/BrowserAuthError.d.ts +250 -250
  83. package/dist/error/BrowserAuthError.mjs +258 -258
  84. package/dist/error/BrowserAuthError.mjs.map +1 -1
  85. package/dist/error/BrowserAuthErrorCodes.d.ts +45 -45
  86. package/dist/error/BrowserAuthErrorCodes.mjs +49 -49
  87. package/dist/error/BrowserAuthErrorCodes.mjs.map +1 -1
  88. package/dist/error/BrowserConfigurationAuthError.d.ts +33 -33
  89. package/dist/error/BrowserConfigurationAuthError.mjs +40 -40
  90. package/dist/error/BrowserConfigurationAuthError.mjs.map +1 -1
  91. package/dist/error/BrowserConfigurationAuthErrorCodes.d.ts +3 -3
  92. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +7 -7
  93. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs.map +1 -1
  94. package/dist/error/NativeAuthError.d.ts +29 -29
  95. package/dist/error/NativeAuthError.mjs +60 -60
  96. package/dist/error/NativeAuthError.mjs.map +1 -1
  97. package/dist/error/NativeAuthErrorCodes.d.ts +2 -2
  98. package/dist/error/NativeAuthErrorCodes.mjs +6 -6
  99. package/dist/error/NativeAuthErrorCodes.mjs.map +1 -1
  100. package/dist/error/NestedAppAuthError.d.ts +14 -14
  101. package/dist/error/NestedAppAuthError.mjs +23 -23
  102. package/dist/error/NestedAppAuthError.mjs.map +1 -1
  103. package/dist/event/EventHandler.d.ts +41 -41
  104. package/dist/event/EventHandler.mjs +119 -119
  105. package/dist/event/EventHandler.mjs.map +1 -1
  106. package/dist/event/EventMessage.d.ts +25 -25
  107. package/dist/event/EventMessage.mjs +68 -68
  108. package/dist/event/EventMessage.mjs.map +1 -1
  109. package/dist/event/EventType.d.ts +28 -28
  110. package/dist/event/EventType.mjs +31 -31
  111. package/dist/event/EventType.mjs.map +1 -1
  112. package/dist/index.d.ts +39 -39
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.mjs +1 -1
  115. package/dist/interaction_client/BaseInteractionClient.d.ts +54 -54
  116. package/dist/interaction_client/BaseInteractionClient.mjs +152 -152
  117. package/dist/interaction_client/BaseInteractionClient.mjs.map +1 -1
  118. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.d.ts +4 -4
  119. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +10 -10
  120. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs.map +1 -1
  121. package/dist/interaction_client/NativeInteractionClient.d.ts +140 -140
  122. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  123. package/dist/interaction_client/NativeInteractionClient.mjs +539 -549
  124. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  125. package/dist/interaction_client/PopupClient.d.ts +105 -105
  126. package/dist/interaction_client/PopupClient.mjs +432 -432
  127. package/dist/interaction_client/PopupClient.mjs.map +1 -1
  128. package/dist/interaction_client/RedirectClient.d.ts +49 -49
  129. package/dist/interaction_client/RedirectClient.mjs +311 -311
  130. package/dist/interaction_client/RedirectClient.mjs.map +1 -1
  131. package/dist/interaction_client/SilentAuthCodeClient.d.ts +23 -23
  132. package/dist/interaction_client/SilentAuthCodeClient.mjs +57 -57
  133. package/dist/interaction_client/SilentAuthCodeClient.mjs.map +1 -1
  134. package/dist/interaction_client/SilentCacheClient.d.ts +24 -24
  135. package/dist/interaction_client/SilentCacheClient.mjs +61 -61
  136. package/dist/interaction_client/SilentCacheClient.mjs.map +1 -1
  137. package/dist/interaction_client/SilentIframeClient.d.ts +32 -32
  138. package/dist/interaction_client/SilentIframeClient.mjs +96 -96
  139. package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
  140. package/dist/interaction_client/SilentRefreshClient.d.ts +20 -20
  141. package/dist/interaction_client/SilentRefreshClient.mjs +43 -43
  142. package/dist/interaction_client/SilentRefreshClient.mjs.map +1 -1
  143. package/dist/interaction_client/StandardInteractionClient.d.ts +54 -54
  144. package/dist/interaction_client/StandardInteractionClient.mjs +222 -222
  145. package/dist/interaction_client/StandardInteractionClient.mjs.map +1 -1
  146. package/dist/interaction_handler/InteractionHandler.d.ts +33 -33
  147. package/dist/interaction_handler/InteractionHandler.mjs +93 -93
  148. package/dist/interaction_handler/InteractionHandler.mjs.map +1 -1
  149. package/dist/interaction_handler/RedirectHandler.d.ts +32 -32
  150. package/dist/interaction_handler/RedirectHandler.mjs +134 -134
  151. package/dist/interaction_handler/RedirectHandler.mjs.map +1 -1
  152. package/dist/interaction_handler/SilentHandler.d.ts +13 -13
  153. package/dist/interaction_handler/SilentHandler.mjs +133 -133
  154. package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
  155. package/dist/naa/AccountInfo.d.ts +11 -11
  156. package/dist/naa/AccountRequests.d.ts +9 -9
  157. package/dist/naa/AuthBridge.d.ts +8 -5
  158. package/dist/naa/AuthBridge.d.ts.map +1 -1
  159. package/dist/naa/BridgeCapabilities.d.ts +3 -3
  160. package/dist/naa/BridgeError.d.ts +9 -9
  161. package/dist/naa/BridgeError.mjs +7 -7
  162. package/dist/naa/BridgeError.mjs.map +1 -1
  163. package/dist/naa/BridgeProxy.d.ts +72 -72
  164. package/dist/naa/BridgeProxy.d.ts.map +1 -1
  165. package/dist/naa/BridgeProxy.mjs +153 -152
  166. package/dist/naa/BridgeProxy.mjs.map +1 -1
  167. package/dist/naa/BridgeRequest.d.ts +6 -6
  168. package/dist/naa/BridgeRequestEnvelope.d.ts +13 -13
  169. package/dist/naa/BridgeResponseEnvelope.d.ts +10 -10
  170. package/dist/naa/BridgeStatusCode.d.ts +10 -10
  171. package/dist/naa/BridgeStatusCode.mjs +15 -15
  172. package/dist/naa/BridgeStatusCode.mjs.map +1 -1
  173. package/dist/naa/IBridgeProxy.d.ts +12 -12
  174. package/dist/naa/InitializeBridgeResponse.d.ts +6 -6
  175. package/dist/naa/TokenRequest.d.ts +19 -19
  176. package/dist/naa/TokenResponse.d.ts +15 -15
  177. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts +23 -23
  178. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +141 -141
  179. package/dist/naa/mapping/NestedAppAuthAdapter.mjs.map +1 -1
  180. package/dist/navigation/INavigationClient.d.ts +16 -16
  181. package/dist/navigation/NavigationClient.d.ts +22 -22
  182. package/dist/navigation/NavigationClient.mjs +40 -40
  183. package/dist/navigation/NavigationClient.mjs.map +1 -1
  184. package/dist/navigation/NavigationOptions.d.ts +12 -12
  185. package/dist/network/FetchClient.d.ts +26 -26
  186. package/dist/network/FetchClient.mjs +99 -99
  187. package/dist/network/FetchClient.mjs.map +1 -1
  188. package/dist/operatingcontext/BaseOperatingContext.d.ts +40 -40
  189. package/dist/operatingcontext/BaseOperatingContext.mjs +44 -44
  190. package/dist/operatingcontext/BaseOperatingContext.mjs.map +1 -1
  191. package/dist/operatingcontext/StandardOperatingContext.d.ts +25 -25
  192. package/dist/operatingcontext/StandardOperatingContext.mjs +43 -43
  193. package/dist/operatingcontext/StandardOperatingContext.mjs.map +1 -1
  194. package/dist/operatingcontext/TeamsAppOperatingContext.d.ts +32 -32
  195. package/dist/operatingcontext/TeamsAppOperatingContext.mjs +85 -85
  196. package/dist/operatingcontext/TeamsAppOperatingContext.mjs.map +1 -1
  197. package/dist/operatingcontext/UnknownOperatingContext.d.ts +25 -25
  198. package/dist/operatingcontext/UnknownOperatingContext.mjs +42 -42
  199. package/dist/operatingcontext/UnknownOperatingContext.mjs.map +1 -1
  200. package/dist/packageMetadata.d.ts +2 -2
  201. package/dist/packageMetadata.d.ts.map +1 -1
  202. package/dist/packageMetadata.mjs +4 -4
  203. package/dist/packageMetadata.mjs.map +1 -1
  204. package/dist/request/AuthorizationCodeRequest.d.ts +8 -8
  205. package/dist/request/AuthorizationUrlRequest.d.ts +8 -8
  206. package/dist/request/ClearCacheRequest.d.ts +10 -10
  207. package/dist/request/EndSessionPopupRequest.d.ts +18 -18
  208. package/dist/request/EndSessionRequest.d.ts +15 -15
  209. package/dist/request/PopupRequest.d.ts +34 -34
  210. package/dist/request/PopupWindowAttributes.d.ts +15 -15
  211. package/dist/request/RedirectRequest.d.ts +35 -35
  212. package/dist/request/SilentRequest.d.ts +32 -32
  213. package/dist/request/SsoSilentRequest.d.ts +29 -29
  214. package/dist/response/AuthenticationResult.d.ts +4 -4
  215. package/dist/response/ResponseHandler.d.ts +7 -7
  216. package/dist/response/ResponseHandler.mjs +36 -36
  217. package/dist/response/ResponseHandler.mjs.map +1 -1
  218. package/dist/telemetry/BrowserPerformanceClient.d.ts +36 -36
  219. package/dist/telemetry/BrowserPerformanceClient.mjs +125 -125
  220. package/dist/telemetry/BrowserPerformanceClient.mjs.map +1 -1
  221. package/dist/telemetry/BrowserPerformanceMeasurement.d.ts +21 -21
  222. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +92 -92
  223. package/dist/telemetry/BrowserPerformanceMeasurement.mjs.map +1 -1
  224. package/dist/utils/BrowserConstants.d.ts +176 -176
  225. package/dist/utils/BrowserConstants.mjs +204 -204
  226. package/dist/utils/BrowserConstants.mjs.map +1 -1
  227. package/dist/utils/BrowserProtocolUtils.d.ts +11 -11
  228. package/dist/utils/BrowserProtocolUtils.mjs +21 -21
  229. package/dist/utils/BrowserProtocolUtils.mjs.map +1 -1
  230. package/dist/utils/BrowserUtils.d.ts +56 -56
  231. package/dist/utils/BrowserUtils.mjs +125 -125
  232. package/dist/utils/BrowserUtils.mjs.map +1 -1
  233. package/lib/msal-browser.cjs +18217 -17928
  234. package/lib/msal-browser.cjs.map +1 -1
  235. package/lib/msal-browser.js +18217 -17928
  236. package/lib/msal-browser.js.map +1 -1
  237. package/lib/msal-browser.min.js +71 -68
  238. package/package.json +103 -102
  239. package/src/app/PublicClientApplication.ts +2 -1
  240. package/src/cache/BrowserCacheManager.ts +31 -4
  241. package/src/cache/DatabaseStorage.ts +1 -1
  242. package/src/cache/TokenCache.ts +33 -29
  243. package/src/config/Configuration.ts +1 -1
  244. package/src/controllers/ControllerFactory.ts +3 -5
  245. package/src/controllers/StandardController.ts +4 -6
  246. package/src/crypto/CryptoOps.ts +1 -1
  247. package/src/crypto/SignedHttpRequest.ts +1 -1
  248. package/src/index.ts +1 -0
  249. package/src/interaction_client/BaseInteractionClient.ts +2 -2
  250. package/src/interaction_client/NativeInteractionClient.ts +23 -20
  251. package/src/interaction_client/PopupClient.ts +1 -1
  252. package/src/interaction_client/RedirectClient.ts +3 -3
  253. package/src/interaction_client/SilentAuthCodeClient.ts +1 -1
  254. package/src/interaction_client/StandardInteractionClient.ts +1 -1
  255. package/src/interaction_handler/SilentHandler.ts +2 -2
  256. package/src/naa/AuthBridge.ts +3 -2
  257. package/src/naa/BridgeProxy.ts +6 -4
  258. package/src/packageMetadata.ts +1 -1
@@ -1,4 +1,4 @@
1
- /*! @azure/msal-browser v3.5.1-beta.1 2023-11-14 */
1
+ /*! @azure/msal-browser v3.6.0 2023-12-01 */
2
2
  'use strict';
3
3
  import { OIDC_DEFAULT_SCOPES, invokeAsync, PerformanceEvents, invoke, ThrottlingUtils, ProtocolUtils, AuthError, ProtocolMode, UrlString, ServerResponseType } from '@azure/msal-common';
4
4
  import { StandardInteractionClient } from './StandardInteractionClient.mjs';
@@ -12,437 +12,437 @@ import { InteractionHandler } from '../interaction_handler/InteractionHandler.mj
12
12
  import { deserializeResponse } from '../response/ResponseHandler.mjs';
13
13
  import { nativeConnectionNotEstablished, emptyNavigateUri, userCancelled, emptyWindowError, popupWindowError } from '../error/BrowserAuthErrorCodes.mjs';
14
14
 
15
- /*
16
- * Copyright (c) Microsoft Corporation. All rights reserved.
17
- * Licensed under the MIT License.
18
- */
19
- class PopupClient extends StandardInteractionClient {
20
- constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl, nativeMessageHandler, correlationId) {
21
- super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeMessageHandler, correlationId);
22
- // Properly sets this reference for the unload event.
23
- this.unloadWindow = this.unloadWindow.bind(this);
24
- this.nativeStorage = nativeStorageImpl;
25
- }
26
- /**
27
- * Acquires tokens by opening a popup window to the /authorize endpoint of the authority
28
- * @param request
29
- */
30
- acquireToken(request) {
31
- try {
32
- const popupName = this.generatePopupName(request.scopes || OIDC_DEFAULT_SCOPES, request.authority || this.config.auth.authority);
33
- const popupWindowAttributes = request.popupWindowAttributes || {};
34
- // asyncPopups flag is true. Acquires token without first opening popup. Popup will be opened later asynchronously.
35
- if (this.config.system.asyncPopups) {
36
- this.logger.verbose("asyncPopups set to true, acquiring token");
37
- // Passes on popup position and dimensions if in request
38
- return this.acquireTokenPopupAsync(request, popupName, popupWindowAttributes);
39
- }
40
- else {
41
- // asyncPopups flag is set to false. Opens popup before acquiring token.
42
- this.logger.verbose("asyncPopup set to false, opening popup before acquiring token");
43
- const popup = this.openSizedPopup("about:blank", popupName, popupWindowAttributes);
44
- return this.acquireTokenPopupAsync(request, popupName, popupWindowAttributes, popup);
45
- }
46
- }
47
- catch (e) {
48
- return Promise.reject(e);
49
- }
50
- }
51
- /**
52
- * Clears local cache for the current user then opens a popup window prompting the user to sign-out of the server
53
- * @param logoutRequest
54
- */
55
- logout(logoutRequest) {
56
- try {
57
- this.logger.verbose("logoutPopup called");
58
- const validLogoutRequest = this.initializeLogoutRequest(logoutRequest);
59
- const popupName = this.generateLogoutPopupName(validLogoutRequest);
60
- const authority = logoutRequest && logoutRequest.authority;
61
- const mainWindowRedirectUri = logoutRequest && logoutRequest.mainWindowRedirectUri;
62
- const popupWindowAttributes = logoutRequest?.popupWindowAttributes || {};
63
- // asyncPopups flag is true. Acquires token without first opening popup. Popup will be opened later asynchronously.
64
- if (this.config.system.asyncPopups) {
65
- this.logger.verbose("asyncPopups set to true");
66
- // Passes on popup position and dimensions if in request
67
- return this.logoutPopupAsync(validLogoutRequest, popupName, popupWindowAttributes, authority, undefined, mainWindowRedirectUri);
68
- }
69
- else {
70
- // asyncPopups flag is set to false. Opens popup before logging out.
71
- this.logger.verbose("asyncPopup set to false, opening popup");
72
- const popup = this.openSizedPopup("about:blank", popupName, popupWindowAttributes);
73
- return this.logoutPopupAsync(validLogoutRequest, popupName, popupWindowAttributes, authority, popup, mainWindowRedirectUri);
74
- }
75
- }
76
- catch (e) {
77
- // Since this function is synchronous we need to reject
78
- return Promise.reject(e);
79
- }
80
- }
81
- /**
82
- * Helper which obtains an access_token for your API via opening a popup window in the user's browser
83
- * @param validRequest
84
- * @param popupName
85
- * @param popup
86
- * @param popupWindowAttributes
87
- *
88
- * @returns A promise that is fulfilled when this function has completed, or rejected if an error was raised.
89
- */
90
- async acquireTokenPopupAsync(request, popupName, popupWindowAttributes, popup) {
91
- this.logger.verbose("acquireTokenPopupAsync called");
92
- const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenPopup);
93
- const validRequest = await invokeAsync(this.initializeAuthorizationRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(request, InteractionType.Popup);
94
- preconnect(validRequest.authority);
95
- try {
96
- // Create auth code request and generate PKCE params
97
- const authCodeRequest = await invokeAsync(this.initializeAuthorizationCodeRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest, this.logger, this.performanceClient, this.correlationId)(validRequest);
98
- // Initialize the client
99
- const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), PerformanceEvents.StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)(serverTelemetryManager, validRequest.authority, validRequest.azureCloudOptions);
100
- const isNativeBroker = NativeMessageHandler.isNativeAvailable(this.config, this.logger, this.nativeMessageHandler, request.authenticationScheme);
101
- // Start measurement for server calls with native brokering enabled
102
- let fetchNativeAccountIdMeasurement;
103
- if (isNativeBroker) {
104
- fetchNativeAccountIdMeasurement =
105
- this.performanceClient.startMeasurement(PerformanceEvents.FetchAccountIdWithNativeBroker, request.correlationId);
106
- }
107
- // Create acquire token url.
108
- const navigateUrl = await authClient.getAuthCodeUrl({
109
- ...validRequest,
110
- nativeBroker: isNativeBroker,
111
- });
112
- // Create popup interaction handler.
113
- const interactionHandler = new InteractionHandler(authClient, this.browserStorage, authCodeRequest, this.logger, this.performanceClient);
114
- // Show the UI once the url has been created. Get the window handle for the popup.
115
- const popupParameters = {
116
- popup,
117
- popupName,
118
- popupWindowAttributes,
119
- };
120
- const popupWindow = this.initiateAuthRequest(navigateUrl, popupParameters);
121
- this.eventHandler.emitEvent(EventType.POPUP_OPENED, InteractionType.Popup, { popupWindow }, null);
122
- // Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
123
- const responseString = await this.monitorPopupForHash(popupWindow);
124
- const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.serverResponseType, this.logger);
125
- // Remove throttle if it exists
126
- ThrottlingUtils.removeThrottle(this.browserStorage, this.config.auth.clientId, authCodeRequest);
127
- if (serverParams.accountId) {
128
- this.logger.verbose("Account id found in hash, calling WAM for token");
129
- // end measurement for server call with native brokering enabled
130
- if (fetchNativeAccountIdMeasurement) {
131
- fetchNativeAccountIdMeasurement.end({
132
- success: true,
133
- isNativeBroker: true,
134
- });
135
- }
136
- if (!this.nativeMessageHandler) {
137
- throw createBrowserAuthError(nativeConnectionNotEstablished);
138
- }
139
- const nativeInteractionClient = new NativeInteractionClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenPopup, this.performanceClient, this.nativeMessageHandler, serverParams.accountId, this.nativeStorage, validRequest.correlationId);
140
- const { userRequestState } = ProtocolUtils.parseRequestState(this.browserCrypto, validRequest.state);
141
- return nativeInteractionClient.acquireToken({
142
- ...validRequest,
143
- state: userRequestState,
144
- prompt: undefined, // Server should handle the prompt, ideally native broker can do this part silently
145
- });
146
- }
147
- // Handle response from hash string.
148
- const result = await interactionHandler.handleCodeResponse(serverParams, validRequest);
149
- return result;
150
- }
151
- catch (e) {
152
- if (popup) {
153
- // Close the synchronous popup if an error is thrown before the window unload event is registered
154
- popup.close();
155
- }
156
- if (e instanceof AuthError) {
157
- e.setCorrelationId(this.correlationId);
158
- serverTelemetryManager.cacheFailedRequest(e);
159
- }
160
- throw e;
161
- }
162
- }
163
- /**
164
- *
165
- * @param validRequest
166
- * @param popupName
167
- * @param requestAuthority
168
- * @param popup
169
- * @param mainWindowRedirectUri
170
- * @param popupWindowAttributes
171
- */
172
- async logoutPopupAsync(validRequest, popupName, popupWindowAttributes, requestAuthority, popup, mainWindowRedirectUri) {
173
- this.logger.verbose("logoutPopupAsync called");
174
- this.eventHandler.emitEvent(EventType.LOGOUT_START, InteractionType.Popup, validRequest);
175
- const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.logoutPopup);
176
- try {
177
- // Clear cache on logout
178
- await this.clearCacheOnLogout(validRequest.account);
179
- // Initialize the client
180
- const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), PerformanceEvents.StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)(serverTelemetryManager, requestAuthority);
181
- try {
182
- authClient.authority.endSessionEndpoint;
183
- }
184
- catch {
185
- if (validRequest.account?.homeAccountId &&
186
- validRequest.postLogoutRedirectUri &&
187
- authClient.authority.protocolMode === ProtocolMode.OIDC) {
188
- void this.browserStorage.removeAccount(validRequest.account?.homeAccountId);
189
- this.eventHandler.emitEvent(EventType.LOGOUT_SUCCESS, InteractionType.Popup, validRequest);
190
- if (mainWindowRedirectUri) {
191
- const navigationOptions = {
192
- apiId: ApiId.logoutPopup,
193
- timeout: this.config.system.redirectNavigationTimeout,
194
- noHistory: false,
195
- };
196
- const absoluteUrl = UrlString.getAbsoluteUrl(mainWindowRedirectUri, getCurrentUri());
197
- await this.navigationClient.navigateInternal(absoluteUrl, navigationOptions);
198
- }
199
- if (popup) {
200
- popup.close();
201
- }
202
- return;
203
- }
204
- }
205
- // Create logout string and navigate user window to logout.
206
- const logoutUri = authClient.getLogoutUri(validRequest);
207
- this.eventHandler.emitEvent(EventType.LOGOUT_SUCCESS, InteractionType.Popup, validRequest);
208
- // Open the popup window to requestUrl.
209
- const popupWindow = this.openPopup(logoutUri, {
210
- popupName,
211
- popupWindowAttributes,
212
- popup,
213
- });
214
- this.eventHandler.emitEvent(EventType.POPUP_OPENED, InteractionType.Popup, { popupWindow }, null);
215
- await this.monitorPopupForHash(popupWindow).catch(() => {
216
- // Swallow any errors related to monitoring the window. Server logout is best effort
217
- });
218
- if (mainWindowRedirectUri) {
219
- const navigationOptions = {
220
- apiId: ApiId.logoutPopup,
221
- timeout: this.config.system.redirectNavigationTimeout,
222
- noHistory: false,
223
- };
224
- const absoluteUrl = UrlString.getAbsoluteUrl(mainWindowRedirectUri, getCurrentUri());
225
- this.logger.verbose("Redirecting main window to url specified in the request");
226
- this.logger.verbosePii(`Redirecting main window to: ${absoluteUrl}`);
227
- await this.navigationClient.navigateInternal(absoluteUrl, navigationOptions);
228
- }
229
- else {
230
- this.logger.verbose("No main window navigation requested");
231
- }
232
- }
233
- catch (e) {
234
- if (popup) {
235
- // Close the synchronous popup if an error is thrown before the window unload event is registered
236
- popup.close();
237
- }
238
- if (e instanceof AuthError) {
239
- e.setCorrelationId(this.correlationId);
240
- serverTelemetryManager.cacheFailedRequest(e);
241
- }
242
- this.browserStorage.setInteractionInProgress(false);
243
- this.eventHandler.emitEvent(EventType.LOGOUT_FAILURE, InteractionType.Popup, null, e);
244
- this.eventHandler.emitEvent(EventType.LOGOUT_END, InteractionType.Popup);
245
- throw e;
246
- }
247
- this.eventHandler.emitEvent(EventType.LOGOUT_END, InteractionType.Popup);
248
- }
249
- /**
250
- * Opens a popup window with given request Url.
251
- * @param requestUrl
252
- */
253
- initiateAuthRequest(requestUrl, params) {
254
- // Check that request url is not empty.
255
- if (requestUrl) {
256
- this.logger.infoPii(`Navigate to: ${requestUrl}`);
257
- // Open the popup window to requestUrl.
258
- return this.openPopup(requestUrl, params);
259
- }
260
- else {
261
- // Throw error if request URL is empty.
262
- this.logger.error("Navigate url is empty");
263
- throw createBrowserAuthError(emptyNavigateUri);
264
- }
265
- }
266
- /**
267
- * Monitors a window until it loads a url with the same origin.
268
- * @param popupWindow - window that is being monitored
269
- * @param timeout - timeout for processing hash once popup is redirected back to application
270
- */
271
- monitorPopupForHash(popupWindow) {
272
- return new Promise((resolve, reject) => {
273
- this.logger.verbose("PopupHandler.monitorPopupForHash - polling started");
274
- const intervalId = setInterval(() => {
275
- // Window is closed
276
- if (popupWindow.closed) {
277
- this.logger.error("PopupHandler.monitorPopupForHash - window closed");
278
- clearInterval(intervalId);
279
- reject(createBrowserAuthError(userCancelled));
280
- return;
281
- }
282
- let href = "";
283
- try {
284
- /*
285
- * Will throw if cross origin,
286
- * which should be caught and ignored
287
- * since we need the interval to keep running while on STS UI.
288
- */
289
- href = popupWindow.location.href;
290
- }
291
- catch (e) { }
292
- // Don't process blank pages or cross domain
293
- if (!href || href === "about:blank") {
294
- return;
295
- }
296
- clearInterval(intervalId);
297
- let responseString = "";
298
- const responseType = this.config.auth.OIDCOptions.serverResponseType;
299
- if (popupWindow) {
300
- if (responseType === ServerResponseType.QUERY) {
301
- responseString = popupWindow.location.search;
302
- }
303
- else {
304
- responseString = popupWindow.location.hash;
305
- }
306
- }
307
- this.logger.verbose("PopupHandler.monitorPopupForHash - popup window is on same origin as caller");
308
- resolve(responseString);
309
- }, this.config.system.pollIntervalMilliseconds);
310
- }).finally(() => {
311
- this.cleanPopup(popupWindow);
312
- });
313
- }
314
- /**
315
- * @hidden
316
- *
317
- * Configures popup window for login.
318
- *
319
- * @param urlNavigate
320
- * @param title
321
- * @param popUpWidth
322
- * @param popUpHeight
323
- * @param popupWindowAttributes
324
- * @ignore
325
- * @hidden
326
- */
327
- openPopup(urlNavigate, popupParams) {
328
- try {
329
- let popupWindow;
330
- // Popup window passed in, setting url to navigate to
331
- if (popupParams.popup) {
332
- popupWindow = popupParams.popup;
333
- this.logger.verbosePii(`Navigating popup window to: ${urlNavigate}`);
334
- popupWindow.location.assign(urlNavigate);
335
- }
336
- else if (typeof popupParams.popup === "undefined") {
337
- // Popup will be undefined if it was not passed in
338
- this.logger.verbosePii(`Opening popup window to: ${urlNavigate}`);
339
- popupWindow = this.openSizedPopup(urlNavigate, popupParams.popupName, popupParams.popupWindowAttributes);
340
- }
341
- // Popup will be null if popups are blocked
342
- if (!popupWindow) {
343
- throw createBrowserAuthError(emptyWindowError);
344
- }
345
- if (popupWindow.focus) {
346
- popupWindow.focus();
347
- }
348
- this.currentWindow = popupWindow;
349
- window.addEventListener("beforeunload", this.unloadWindow);
350
- return popupWindow;
351
- }
352
- catch (e) {
353
- this.logger.error("error opening popup " + e.message);
354
- this.browserStorage.setInteractionInProgress(false);
355
- throw createBrowserAuthError(popupWindowError);
356
- }
357
- }
358
- /**
359
- * Helper function to set popup window dimensions and position
360
- * @param urlNavigate
361
- * @param popupName
362
- * @param popupWindowAttributes
363
- * @returns
364
- */
365
- openSizedPopup(urlNavigate, popupName, popupWindowAttributes) {
366
- /**
367
- * adding winLeft and winTop to account for dual monitor
368
- * using screenLeft and screenTop for IE8 and earlier
369
- */
370
- const winLeft = window.screenLeft ? window.screenLeft : window.screenX;
371
- const winTop = window.screenTop ? window.screenTop : window.screenY;
372
- /**
373
- * window.innerWidth displays browser window"s height and width excluding toolbars
374
- * using document.documentElement.clientWidth for IE8 and earlier
375
- */
376
- const winWidth = window.innerWidth ||
377
- document.documentElement.clientWidth ||
378
- document.body.clientWidth;
379
- const winHeight = window.innerHeight ||
380
- document.documentElement.clientHeight ||
381
- document.body.clientHeight;
382
- let width = popupWindowAttributes.popupSize?.width;
383
- let height = popupWindowAttributes.popupSize?.height;
384
- let top = popupWindowAttributes.popupPosition?.top;
385
- let left = popupWindowAttributes.popupPosition?.left;
386
- if (!width || width < 0 || width > winWidth) {
387
- this.logger.verbose("Default popup window width used. Window width not configured or invalid.");
388
- width = BrowserConstants.POPUP_WIDTH;
389
- }
390
- if (!height || height < 0 || height > winHeight) {
391
- this.logger.verbose("Default popup window height used. Window height not configured or invalid.");
392
- height = BrowserConstants.POPUP_HEIGHT;
393
- }
394
- if (!top || top < 0 || top > winHeight) {
395
- this.logger.verbose("Default popup window top position used. Window top not configured or invalid.");
396
- top = Math.max(0, winHeight / 2 - BrowserConstants.POPUP_HEIGHT / 2 + winTop);
397
- }
398
- if (!left || left < 0 || left > winWidth) {
399
- this.logger.verbose("Default popup window left position used. Window left not configured or invalid.");
400
- left = Math.max(0, winWidth / 2 - BrowserConstants.POPUP_WIDTH / 2 + winLeft);
401
- }
402
- return window.open(urlNavigate, popupName, `width=${width}, height=${height}, top=${top}, left=${left}, scrollbars=yes`);
403
- }
404
- /**
405
- * Event callback to unload main window.
406
- */
407
- unloadWindow(e) {
408
- this.browserStorage.cleanRequestByInteractionType(InteractionType.Popup);
409
- if (this.currentWindow) {
410
- this.currentWindow.close();
411
- }
412
- // Guarantees browser unload will happen, so no other errors will be thrown.
413
- e.preventDefault();
414
- }
415
- /**
416
- * Closes popup, removes any state vars created during popup calls.
417
- * @param popupWindow
418
- */
419
- cleanPopup(popupWindow) {
420
- if (popupWindow) {
421
- // Close window.
422
- popupWindow.close();
423
- }
424
- // Remove window unload function
425
- window.removeEventListener("beforeunload", this.unloadWindow);
426
- // Interaction is completed - remove interaction status.
427
- this.browserStorage.setInteractionInProgress(false);
428
- }
429
- /**
430
- * Generates the name for the popup based on the client id and request
431
- * @param clientId
432
- * @param request
433
- */
434
- generatePopupName(scopes, authority) {
435
- return `${BrowserConstants.POPUP_NAME_PREFIX}.${this.config.auth.clientId}.${scopes.join("-")}.${authority}.${this.correlationId}`;
436
- }
437
- /**
438
- * Generates the name for the popup based on the client id and request for logouts
439
- * @param clientId
440
- * @param request
441
- */
442
- generateLogoutPopupName(request) {
443
- const homeAccountId = request.account && request.account.homeAccountId;
444
- return `${BrowserConstants.POPUP_NAME_PREFIX}.${this.config.auth.clientId}.${homeAccountId}.${this.correlationId}`;
445
- }
15
+ /*
16
+ * Copyright (c) Microsoft Corporation. All rights reserved.
17
+ * Licensed under the MIT License.
18
+ */
19
+ class PopupClient extends StandardInteractionClient {
20
+ constructor(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeStorageImpl, nativeMessageHandler, correlationId) {
21
+ super(config, storageImpl, browserCrypto, logger, eventHandler, navigationClient, performanceClient, nativeMessageHandler, correlationId);
22
+ // Properly sets this reference for the unload event.
23
+ this.unloadWindow = this.unloadWindow.bind(this);
24
+ this.nativeStorage = nativeStorageImpl;
25
+ }
26
+ /**
27
+ * Acquires tokens by opening a popup window to the /authorize endpoint of the authority
28
+ * @param request
29
+ */
30
+ acquireToken(request) {
31
+ try {
32
+ const popupName = this.generatePopupName(request.scopes || OIDC_DEFAULT_SCOPES, request.authority || this.config.auth.authority);
33
+ const popupWindowAttributes = request.popupWindowAttributes || {};
34
+ // asyncPopups flag is true. Acquires token without first opening popup. Popup will be opened later asynchronously.
35
+ if (this.config.system.asyncPopups) {
36
+ this.logger.verbose("asyncPopups set to true, acquiring token");
37
+ // Passes on popup position and dimensions if in request
38
+ return this.acquireTokenPopupAsync(request, popupName, popupWindowAttributes);
39
+ }
40
+ else {
41
+ // asyncPopups flag is set to false. Opens popup before acquiring token.
42
+ this.logger.verbose("asyncPopup set to false, opening popup before acquiring token");
43
+ const popup = this.openSizedPopup("about:blank", popupName, popupWindowAttributes);
44
+ return this.acquireTokenPopupAsync(request, popupName, popupWindowAttributes, popup);
45
+ }
46
+ }
47
+ catch (e) {
48
+ return Promise.reject(e);
49
+ }
50
+ }
51
+ /**
52
+ * Clears local cache for the current user then opens a popup window prompting the user to sign-out of the server
53
+ * @param logoutRequest
54
+ */
55
+ logout(logoutRequest) {
56
+ try {
57
+ this.logger.verbose("logoutPopup called");
58
+ const validLogoutRequest = this.initializeLogoutRequest(logoutRequest);
59
+ const popupName = this.generateLogoutPopupName(validLogoutRequest);
60
+ const authority = logoutRequest && logoutRequest.authority;
61
+ const mainWindowRedirectUri = logoutRequest && logoutRequest.mainWindowRedirectUri;
62
+ const popupWindowAttributes = logoutRequest?.popupWindowAttributes || {};
63
+ // asyncPopups flag is true. Acquires token without first opening popup. Popup will be opened later asynchronously.
64
+ if (this.config.system.asyncPopups) {
65
+ this.logger.verbose("asyncPopups set to true");
66
+ // Passes on popup position and dimensions if in request
67
+ return this.logoutPopupAsync(validLogoutRequest, popupName, popupWindowAttributes, authority, undefined, mainWindowRedirectUri);
68
+ }
69
+ else {
70
+ // asyncPopups flag is set to false. Opens popup before logging out.
71
+ this.logger.verbose("asyncPopup set to false, opening popup");
72
+ const popup = this.openSizedPopup("about:blank", popupName, popupWindowAttributes);
73
+ return this.logoutPopupAsync(validLogoutRequest, popupName, popupWindowAttributes, authority, popup, mainWindowRedirectUri);
74
+ }
75
+ }
76
+ catch (e) {
77
+ // Since this function is synchronous we need to reject
78
+ return Promise.reject(e);
79
+ }
80
+ }
81
+ /**
82
+ * Helper which obtains an access_token for your API via opening a popup window in the user's browser
83
+ * @param validRequest
84
+ * @param popupName
85
+ * @param popup
86
+ * @param popupWindowAttributes
87
+ *
88
+ * @returns A promise that is fulfilled when this function has completed, or rejected if an error was raised.
89
+ */
90
+ async acquireTokenPopupAsync(request, popupName, popupWindowAttributes, popup) {
91
+ this.logger.verbose("acquireTokenPopupAsync called");
92
+ const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.acquireTokenPopup);
93
+ const validRequest = await invokeAsync(this.initializeAuthorizationRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest, this.logger, this.performanceClient, this.correlationId)(request, InteractionType.Popup);
94
+ preconnect(validRequest.authority);
95
+ try {
96
+ // Create auth code request and generate PKCE params
97
+ const authCodeRequest = await invokeAsync(this.initializeAuthorizationCodeRequest.bind(this), PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest, this.logger, this.performanceClient, this.correlationId)(validRequest);
98
+ // Initialize the client
99
+ const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), PerformanceEvents.StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)(serverTelemetryManager, validRequest.authority, validRequest.azureCloudOptions);
100
+ const isNativeBroker = NativeMessageHandler.isNativeAvailable(this.config, this.logger, this.nativeMessageHandler, request.authenticationScheme);
101
+ // Start measurement for server calls with native brokering enabled
102
+ let fetchNativeAccountIdMeasurement;
103
+ if (isNativeBroker) {
104
+ fetchNativeAccountIdMeasurement =
105
+ this.performanceClient.startMeasurement(PerformanceEvents.FetchAccountIdWithNativeBroker, request.correlationId);
106
+ }
107
+ // Create acquire token url.
108
+ const navigateUrl = await authClient.getAuthCodeUrl({
109
+ ...validRequest,
110
+ nativeBroker: isNativeBroker,
111
+ });
112
+ // Create popup interaction handler.
113
+ const interactionHandler = new InteractionHandler(authClient, this.browserStorage, authCodeRequest, this.logger, this.performanceClient);
114
+ // Show the UI once the url has been created. Get the window handle for the popup.
115
+ const popupParameters = {
116
+ popup,
117
+ popupName,
118
+ popupWindowAttributes,
119
+ };
120
+ const popupWindow = this.initiateAuthRequest(navigateUrl, popupParameters);
121
+ this.eventHandler.emitEvent(EventType.POPUP_OPENED, InteractionType.Popup, { popupWindow }, null);
122
+ // Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
123
+ const responseString = await this.monitorPopupForHash(popupWindow);
124
+ const serverParams = invoke(deserializeResponse, PerformanceEvents.DeserializeResponse, this.logger, this.performanceClient, this.correlationId)(responseString, this.config.auth.OIDCOptions.serverResponseType, this.logger);
125
+ // Remove throttle if it exists
126
+ ThrottlingUtils.removeThrottle(this.browserStorage, this.config.auth.clientId, authCodeRequest);
127
+ if (serverParams.accountId) {
128
+ this.logger.verbose("Account id found in hash, calling WAM for token");
129
+ // end measurement for server call with native brokering enabled
130
+ if (fetchNativeAccountIdMeasurement) {
131
+ fetchNativeAccountIdMeasurement.end({
132
+ success: true,
133
+ isNativeBroker: true,
134
+ });
135
+ }
136
+ if (!this.nativeMessageHandler) {
137
+ throw createBrowserAuthError(nativeConnectionNotEstablished);
138
+ }
139
+ const nativeInteractionClient = new NativeInteractionClient(this.config, this.browserStorage, this.browserCrypto, this.logger, this.eventHandler, this.navigationClient, ApiId.acquireTokenPopup, this.performanceClient, this.nativeMessageHandler, serverParams.accountId, this.nativeStorage, validRequest.correlationId);
140
+ const { userRequestState } = ProtocolUtils.parseRequestState(this.browserCrypto, validRequest.state);
141
+ return await nativeInteractionClient.acquireToken({
142
+ ...validRequest,
143
+ state: userRequestState,
144
+ prompt: undefined, // Server should handle the prompt, ideally native broker can do this part silently
145
+ });
146
+ }
147
+ // Handle response from hash string.
148
+ const result = await interactionHandler.handleCodeResponse(serverParams, validRequest);
149
+ return result;
150
+ }
151
+ catch (e) {
152
+ if (popup) {
153
+ // Close the synchronous popup if an error is thrown before the window unload event is registered
154
+ popup.close();
155
+ }
156
+ if (e instanceof AuthError) {
157
+ e.setCorrelationId(this.correlationId);
158
+ serverTelemetryManager.cacheFailedRequest(e);
159
+ }
160
+ throw e;
161
+ }
162
+ }
163
+ /**
164
+ *
165
+ * @param validRequest
166
+ * @param popupName
167
+ * @param requestAuthority
168
+ * @param popup
169
+ * @param mainWindowRedirectUri
170
+ * @param popupWindowAttributes
171
+ */
172
+ async logoutPopupAsync(validRequest, popupName, popupWindowAttributes, requestAuthority, popup, mainWindowRedirectUri) {
173
+ this.logger.verbose("logoutPopupAsync called");
174
+ this.eventHandler.emitEvent(EventType.LOGOUT_START, InteractionType.Popup, validRequest);
175
+ const serverTelemetryManager = this.initializeServerTelemetryManager(ApiId.logoutPopup);
176
+ try {
177
+ // Clear cache on logout
178
+ await this.clearCacheOnLogout(validRequest.account);
179
+ // Initialize the client
180
+ const authClient = await invokeAsync(this.createAuthCodeClient.bind(this), PerformanceEvents.StandardInteractionClientCreateAuthCodeClient, this.logger, this.performanceClient, this.correlationId)(serverTelemetryManager, requestAuthority);
181
+ try {
182
+ authClient.authority.endSessionEndpoint;
183
+ }
184
+ catch {
185
+ if (validRequest.account?.homeAccountId &&
186
+ validRequest.postLogoutRedirectUri &&
187
+ authClient.authority.protocolMode === ProtocolMode.OIDC) {
188
+ void this.browserStorage.removeAccount(validRequest.account?.homeAccountId);
189
+ this.eventHandler.emitEvent(EventType.LOGOUT_SUCCESS, InteractionType.Popup, validRequest);
190
+ if (mainWindowRedirectUri) {
191
+ const navigationOptions = {
192
+ apiId: ApiId.logoutPopup,
193
+ timeout: this.config.system.redirectNavigationTimeout,
194
+ noHistory: false,
195
+ };
196
+ const absoluteUrl = UrlString.getAbsoluteUrl(mainWindowRedirectUri, getCurrentUri());
197
+ await this.navigationClient.navigateInternal(absoluteUrl, navigationOptions);
198
+ }
199
+ if (popup) {
200
+ popup.close();
201
+ }
202
+ return;
203
+ }
204
+ }
205
+ // Create logout string and navigate user window to logout.
206
+ const logoutUri = authClient.getLogoutUri(validRequest);
207
+ this.eventHandler.emitEvent(EventType.LOGOUT_SUCCESS, InteractionType.Popup, validRequest);
208
+ // Open the popup window to requestUrl.
209
+ const popupWindow = this.openPopup(logoutUri, {
210
+ popupName,
211
+ popupWindowAttributes,
212
+ popup,
213
+ });
214
+ this.eventHandler.emitEvent(EventType.POPUP_OPENED, InteractionType.Popup, { popupWindow }, null);
215
+ await this.monitorPopupForHash(popupWindow).catch(() => {
216
+ // Swallow any errors related to monitoring the window. Server logout is best effort
217
+ });
218
+ if (mainWindowRedirectUri) {
219
+ const navigationOptions = {
220
+ apiId: ApiId.logoutPopup,
221
+ timeout: this.config.system.redirectNavigationTimeout,
222
+ noHistory: false,
223
+ };
224
+ const absoluteUrl = UrlString.getAbsoluteUrl(mainWindowRedirectUri, getCurrentUri());
225
+ this.logger.verbose("Redirecting main window to url specified in the request");
226
+ this.logger.verbosePii(`Redirecting main window to: ${absoluteUrl}`);
227
+ await this.navigationClient.navigateInternal(absoluteUrl, navigationOptions);
228
+ }
229
+ else {
230
+ this.logger.verbose("No main window navigation requested");
231
+ }
232
+ }
233
+ catch (e) {
234
+ if (popup) {
235
+ // Close the synchronous popup if an error is thrown before the window unload event is registered
236
+ popup.close();
237
+ }
238
+ if (e instanceof AuthError) {
239
+ e.setCorrelationId(this.correlationId);
240
+ serverTelemetryManager.cacheFailedRequest(e);
241
+ }
242
+ this.browserStorage.setInteractionInProgress(false);
243
+ this.eventHandler.emitEvent(EventType.LOGOUT_FAILURE, InteractionType.Popup, null, e);
244
+ this.eventHandler.emitEvent(EventType.LOGOUT_END, InteractionType.Popup);
245
+ throw e;
246
+ }
247
+ this.eventHandler.emitEvent(EventType.LOGOUT_END, InteractionType.Popup);
248
+ }
249
+ /**
250
+ * Opens a popup window with given request Url.
251
+ * @param requestUrl
252
+ */
253
+ initiateAuthRequest(requestUrl, params) {
254
+ // Check that request url is not empty.
255
+ if (requestUrl) {
256
+ this.logger.infoPii(`Navigate to: ${requestUrl}`);
257
+ // Open the popup window to requestUrl.
258
+ return this.openPopup(requestUrl, params);
259
+ }
260
+ else {
261
+ // Throw error if request URL is empty.
262
+ this.logger.error("Navigate url is empty");
263
+ throw createBrowserAuthError(emptyNavigateUri);
264
+ }
265
+ }
266
+ /**
267
+ * Monitors a window until it loads a url with the same origin.
268
+ * @param popupWindow - window that is being monitored
269
+ * @param timeout - timeout for processing hash once popup is redirected back to application
270
+ */
271
+ monitorPopupForHash(popupWindow) {
272
+ return new Promise((resolve, reject) => {
273
+ this.logger.verbose("PopupHandler.monitorPopupForHash - polling started");
274
+ const intervalId = setInterval(() => {
275
+ // Window is closed
276
+ if (popupWindow.closed) {
277
+ this.logger.error("PopupHandler.monitorPopupForHash - window closed");
278
+ clearInterval(intervalId);
279
+ reject(createBrowserAuthError(userCancelled));
280
+ return;
281
+ }
282
+ let href = "";
283
+ try {
284
+ /*
285
+ * Will throw if cross origin,
286
+ * which should be caught and ignored
287
+ * since we need the interval to keep running while on STS UI.
288
+ */
289
+ href = popupWindow.location.href;
290
+ }
291
+ catch (e) { }
292
+ // Don't process blank pages or cross domain
293
+ if (!href || href === "about:blank") {
294
+ return;
295
+ }
296
+ clearInterval(intervalId);
297
+ let responseString = "";
298
+ const responseType = this.config.auth.OIDCOptions.serverResponseType;
299
+ if (popupWindow) {
300
+ if (responseType === ServerResponseType.QUERY) {
301
+ responseString = popupWindow.location.search;
302
+ }
303
+ else {
304
+ responseString = popupWindow.location.hash;
305
+ }
306
+ }
307
+ this.logger.verbose("PopupHandler.monitorPopupForHash - popup window is on same origin as caller");
308
+ resolve(responseString);
309
+ }, this.config.system.pollIntervalMilliseconds);
310
+ }).finally(() => {
311
+ this.cleanPopup(popupWindow);
312
+ });
313
+ }
314
+ /**
315
+ * @hidden
316
+ *
317
+ * Configures popup window for login.
318
+ *
319
+ * @param urlNavigate
320
+ * @param title
321
+ * @param popUpWidth
322
+ * @param popUpHeight
323
+ * @param popupWindowAttributes
324
+ * @ignore
325
+ * @hidden
326
+ */
327
+ openPopup(urlNavigate, popupParams) {
328
+ try {
329
+ let popupWindow;
330
+ // Popup window passed in, setting url to navigate to
331
+ if (popupParams.popup) {
332
+ popupWindow = popupParams.popup;
333
+ this.logger.verbosePii(`Navigating popup window to: ${urlNavigate}`);
334
+ popupWindow.location.assign(urlNavigate);
335
+ }
336
+ else if (typeof popupParams.popup === "undefined") {
337
+ // Popup will be undefined if it was not passed in
338
+ this.logger.verbosePii(`Opening popup window to: ${urlNavigate}`);
339
+ popupWindow = this.openSizedPopup(urlNavigate, popupParams.popupName, popupParams.popupWindowAttributes);
340
+ }
341
+ // Popup will be null if popups are blocked
342
+ if (!popupWindow) {
343
+ throw createBrowserAuthError(emptyWindowError);
344
+ }
345
+ if (popupWindow.focus) {
346
+ popupWindow.focus();
347
+ }
348
+ this.currentWindow = popupWindow;
349
+ window.addEventListener("beforeunload", this.unloadWindow);
350
+ return popupWindow;
351
+ }
352
+ catch (e) {
353
+ this.logger.error("error opening popup " + e.message);
354
+ this.browserStorage.setInteractionInProgress(false);
355
+ throw createBrowserAuthError(popupWindowError);
356
+ }
357
+ }
358
+ /**
359
+ * Helper function to set popup window dimensions and position
360
+ * @param urlNavigate
361
+ * @param popupName
362
+ * @param popupWindowAttributes
363
+ * @returns
364
+ */
365
+ openSizedPopup(urlNavigate, popupName, popupWindowAttributes) {
366
+ /**
367
+ * adding winLeft and winTop to account for dual monitor
368
+ * using screenLeft and screenTop for IE8 and earlier
369
+ */
370
+ const winLeft = window.screenLeft ? window.screenLeft : window.screenX;
371
+ const winTop = window.screenTop ? window.screenTop : window.screenY;
372
+ /**
373
+ * window.innerWidth displays browser window"s height and width excluding toolbars
374
+ * using document.documentElement.clientWidth for IE8 and earlier
375
+ */
376
+ const winWidth = window.innerWidth ||
377
+ document.documentElement.clientWidth ||
378
+ document.body.clientWidth;
379
+ const winHeight = window.innerHeight ||
380
+ document.documentElement.clientHeight ||
381
+ document.body.clientHeight;
382
+ let width = popupWindowAttributes.popupSize?.width;
383
+ let height = popupWindowAttributes.popupSize?.height;
384
+ let top = popupWindowAttributes.popupPosition?.top;
385
+ let left = popupWindowAttributes.popupPosition?.left;
386
+ if (!width || width < 0 || width > winWidth) {
387
+ this.logger.verbose("Default popup window width used. Window width not configured or invalid.");
388
+ width = BrowserConstants.POPUP_WIDTH;
389
+ }
390
+ if (!height || height < 0 || height > winHeight) {
391
+ this.logger.verbose("Default popup window height used. Window height not configured or invalid.");
392
+ height = BrowserConstants.POPUP_HEIGHT;
393
+ }
394
+ if (!top || top < 0 || top > winHeight) {
395
+ this.logger.verbose("Default popup window top position used. Window top not configured or invalid.");
396
+ top = Math.max(0, winHeight / 2 - BrowserConstants.POPUP_HEIGHT / 2 + winTop);
397
+ }
398
+ if (!left || left < 0 || left > winWidth) {
399
+ this.logger.verbose("Default popup window left position used. Window left not configured or invalid.");
400
+ left = Math.max(0, winWidth / 2 - BrowserConstants.POPUP_WIDTH / 2 + winLeft);
401
+ }
402
+ return window.open(urlNavigate, popupName, `width=${width}, height=${height}, top=${top}, left=${left}, scrollbars=yes`);
403
+ }
404
+ /**
405
+ * Event callback to unload main window.
406
+ */
407
+ unloadWindow(e) {
408
+ this.browserStorage.cleanRequestByInteractionType(InteractionType.Popup);
409
+ if (this.currentWindow) {
410
+ this.currentWindow.close();
411
+ }
412
+ // Guarantees browser unload will happen, so no other errors will be thrown.
413
+ e.preventDefault();
414
+ }
415
+ /**
416
+ * Closes popup, removes any state vars created during popup calls.
417
+ * @param popupWindow
418
+ */
419
+ cleanPopup(popupWindow) {
420
+ if (popupWindow) {
421
+ // Close window.
422
+ popupWindow.close();
423
+ }
424
+ // Remove window unload function
425
+ window.removeEventListener("beforeunload", this.unloadWindow);
426
+ // Interaction is completed - remove interaction status.
427
+ this.browserStorage.setInteractionInProgress(false);
428
+ }
429
+ /**
430
+ * Generates the name for the popup based on the client id and request
431
+ * @param clientId
432
+ * @param request
433
+ */
434
+ generatePopupName(scopes, authority) {
435
+ return `${BrowserConstants.POPUP_NAME_PREFIX}.${this.config.auth.clientId}.${scopes.join("-")}.${authority}.${this.correlationId}`;
436
+ }
437
+ /**
438
+ * Generates the name for the popup based on the client id and request for logouts
439
+ * @param clientId
440
+ * @param request
441
+ */
442
+ generateLogoutPopupName(request) {
443
+ const homeAccountId = request.account && request.account.homeAccountId;
444
+ return `${BrowserConstants.POPUP_NAME_PREFIX}.${this.config.auth.clientId}.${homeAccountId}.${this.correlationId}`;
445
+ }
446
446
  }
447
447
 
448
448
  export { PopupClient };