@azure/msal-browser 4.7.0 → 4.9.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 (214) hide show
  1. package/dist/app/IPublicClientApplication.mjs +1 -1
  2. package/dist/app/PublicClientApplication.mjs +1 -1
  3. package/dist/app/PublicClientNext.mjs +1 -1
  4. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
  5. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  6. package/dist/cache/AccountManager.mjs +1 -1
  7. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  8. package/dist/cache/BrowserCacheManager.d.ts +4 -41
  9. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  10. package/dist/cache/BrowserCacheManager.mjs +18 -143
  11. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  12. package/dist/cache/CacheHelpers.mjs +1 -1
  13. package/dist/cache/CookieStorage.mjs +1 -1
  14. package/dist/cache/DatabaseStorage.mjs +1 -1
  15. package/dist/cache/LocalStorage.mjs +1 -1
  16. package/dist/cache/MemoryStorage.mjs +1 -1
  17. package/dist/cache/SessionStorage.mjs +1 -1
  18. package/dist/cache/TokenCache.mjs +1 -1
  19. package/dist/config/Configuration.d.ts.map +1 -1
  20. package/dist/config/Configuration.mjs +12 -3
  21. package/dist/config/Configuration.mjs.map +1 -1
  22. package/dist/controllers/ControllerFactory.mjs +1 -1
  23. package/dist/controllers/NestedAppAuthController.d.ts +2 -2
  24. package/dist/controllers/NestedAppAuthController.d.ts.map +1 -1
  25. package/dist/controllers/NestedAppAuthController.mjs +1 -1
  26. package/dist/controllers/NestedAppAuthController.mjs.map +1 -1
  27. package/dist/controllers/StandardController.d.ts.map +1 -1
  28. package/dist/controllers/StandardController.mjs +28 -16
  29. package/dist/controllers/StandardController.mjs.map +1 -1
  30. package/dist/controllers/UnknownOperatingContextController.d.ts +2 -2
  31. package/dist/controllers/UnknownOperatingContextController.d.ts.map +1 -1
  32. package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
  33. package/dist/controllers/UnknownOperatingContextController.mjs.map +1 -1
  34. package/dist/crypto/BrowserCrypto.d.ts +11 -0
  35. package/dist/crypto/BrowserCrypto.d.ts.map +1 -1
  36. package/dist/crypto/BrowserCrypto.mjs +68 -5
  37. package/dist/crypto/BrowserCrypto.mjs.map +1 -1
  38. package/dist/crypto/CryptoOps.mjs +1 -1
  39. package/dist/crypto/PkceGenerator.mjs +1 -1
  40. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  41. package/dist/encode/Base64Decode.mjs +1 -1
  42. package/dist/encode/Base64Encode.mjs +1 -1
  43. package/dist/error/BrowserAuthError.d.ts +3 -5
  44. package/dist/error/BrowserAuthError.d.ts.map +1 -1
  45. package/dist/error/BrowserAuthError.mjs +5 -7
  46. package/dist/error/BrowserAuthError.mjs.map +1 -1
  47. package/dist/error/BrowserAuthErrorCodes.d.ts +3 -1
  48. package/dist/error/BrowserAuthErrorCodes.d.ts.map +1 -1
  49. package/dist/error/BrowserAuthErrorCodes.mjs +6 -4
  50. package/dist/error/BrowserAuthErrorCodes.mjs.map +1 -1
  51. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  52. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  53. package/dist/error/NativeAuthError.mjs +1 -1
  54. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  55. package/dist/error/NestedAppAuthError.mjs +1 -1
  56. package/dist/event/EventHandler.mjs +1 -1
  57. package/dist/event/EventMessage.mjs +1 -1
  58. package/dist/event/EventType.mjs +1 -1
  59. package/dist/index.mjs +1 -1
  60. package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
  61. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  62. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  63. package/dist/interaction_client/NativeInteractionClient.mjs +9 -4
  64. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  65. package/dist/interaction_client/PopupClient.d.ts +14 -1
  66. package/dist/interaction_client/PopupClient.d.ts.map +1 -1
  67. package/dist/interaction_client/PopupClient.mjs +66 -57
  68. package/dist/interaction_client/PopupClient.mjs.map +1 -1
  69. package/dist/interaction_client/RedirectClient.d.ts +21 -4
  70. package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
  71. package/dist/interaction_client/RedirectClient.mjs +133 -70
  72. package/dist/interaction_client/RedirectClient.mjs.map +1 -1
  73. package/dist/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
  74. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  75. package/dist/interaction_client/SilentAuthCodeClient.mjs.map +1 -1
  76. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  77. package/dist/interaction_client/SilentIframeClient.d.ts +13 -3
  78. package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
  79. package/dist/interaction_client/SilentIframeClient.mjs +64 -41
  80. package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
  81. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  82. package/dist/interaction_client/StandardInteractionClient.d.ts +2 -9
  83. package/dist/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  84. package/dist/interaction_client/StandardInteractionClient.mjs +2 -22
  85. package/dist/interaction_client/StandardInteractionClient.mjs.map +1 -1
  86. package/dist/interaction_handler/InteractionHandler.d.ts +4 -5
  87. package/dist/interaction_handler/InteractionHandler.d.ts.map +1 -1
  88. package/dist/interaction_handler/InteractionHandler.mjs +3 -3
  89. package/dist/interaction_handler/InteractionHandler.mjs.map +1 -1
  90. package/dist/interaction_handler/SilentHandler.d.ts +4 -2
  91. package/dist/interaction_handler/SilentHandler.d.ts.map +1 -1
  92. package/dist/interaction_handler/SilentHandler.mjs +13 -3
  93. package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
  94. package/dist/naa/BridgeError.mjs +1 -1
  95. package/dist/naa/BridgeProxy.mjs +1 -1
  96. package/dist/naa/BridgeStatusCode.mjs +1 -1
  97. package/dist/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -1
  98. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +2 -3
  99. package/dist/naa/mapping/NestedAppAuthAdapter.mjs.map +1 -1
  100. package/dist/navigation/NavigationClient.mjs +1 -1
  101. package/dist/network/FetchClient.mjs +1 -1
  102. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  103. package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
  104. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  105. package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
  106. package/dist/packageMetadata.d.ts +1 -1
  107. package/dist/packageMetadata.mjs +2 -2
  108. package/dist/protocol/Authorize.d.ts +65 -0
  109. package/dist/protocol/Authorize.d.ts.map +1 -0
  110. package/dist/protocol/Authorize.mjs +217 -0
  111. package/dist/protocol/Authorize.mjs.map +1 -0
  112. package/dist/request/AuthorizationUrlRequest.d.ts +2 -4
  113. package/dist/request/AuthorizationUrlRequest.d.ts.map +1 -1
  114. package/dist/request/PopupRequest.d.ts +1 -1
  115. package/dist/request/PopupRequest.d.ts.map +1 -1
  116. package/dist/request/RedirectRequest.d.ts +1 -1
  117. package/dist/request/RedirectRequest.d.ts.map +1 -1
  118. package/dist/request/RequestHelpers.mjs +1 -1
  119. package/dist/request/SsoSilentRequest.d.ts +1 -1
  120. package/dist/request/SsoSilentRequest.d.ts.map +1 -1
  121. package/dist/response/ResponseHandler.d.ts +3 -3
  122. package/dist/response/ResponseHandler.d.ts.map +1 -1
  123. package/dist/response/ResponseHandler.mjs +1 -1
  124. package/dist/response/ResponseHandler.mjs.map +1 -1
  125. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  126. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  127. package/dist/utils/BrowserConstants.d.ts +1 -10
  128. package/dist/utils/BrowserConstants.d.ts.map +1 -1
  129. package/dist/utils/BrowserConstants.mjs +2 -11
  130. package/dist/utils/BrowserConstants.mjs.map +1 -1
  131. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  132. package/dist/utils/BrowserUtils.mjs +1 -1
  133. package/lib/msal-browser.cjs +2402 -2345
  134. package/lib/msal-browser.cjs.map +1 -1
  135. package/lib/msal-browser.js +2402 -2345
  136. package/lib/msal-browser.js.map +1 -1
  137. package/lib/msal-browser.min.js +68 -66
  138. package/lib/types/cache/BrowserCacheManager.d.ts +4 -41
  139. package/lib/types/cache/BrowserCacheManager.d.ts.map +1 -1
  140. package/lib/types/config/Configuration.d.ts.map +1 -1
  141. package/lib/types/controllers/NestedAppAuthController.d.ts +2 -2
  142. package/lib/types/controllers/NestedAppAuthController.d.ts.map +1 -1
  143. package/lib/types/controllers/StandardController.d.ts.map +1 -1
  144. package/lib/types/controllers/UnknownOperatingContextController.d.ts +2 -2
  145. package/lib/types/controllers/UnknownOperatingContextController.d.ts.map +1 -1
  146. package/lib/types/crypto/BrowserCrypto.d.ts +11 -0
  147. package/lib/types/crypto/BrowserCrypto.d.ts.map +1 -1
  148. package/lib/types/error/BrowserAuthError.d.ts +3 -5
  149. package/lib/types/error/BrowserAuthError.d.ts.map +1 -1
  150. package/lib/types/error/BrowserAuthErrorCodes.d.ts +3 -1
  151. package/lib/types/error/BrowserAuthErrorCodes.d.ts.map +1 -1
  152. package/lib/types/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  153. package/lib/types/interaction_client/PopupClient.d.ts +14 -1
  154. package/lib/types/interaction_client/PopupClient.d.ts.map +1 -1
  155. package/lib/types/interaction_client/RedirectClient.d.ts +21 -4
  156. package/lib/types/interaction_client/RedirectClient.d.ts.map +1 -1
  157. package/lib/types/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
  158. package/lib/types/interaction_client/SilentIframeClient.d.ts +13 -3
  159. package/lib/types/interaction_client/SilentIframeClient.d.ts.map +1 -1
  160. package/lib/types/interaction_client/StandardInteractionClient.d.ts +2 -9
  161. package/lib/types/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  162. package/lib/types/interaction_handler/InteractionHandler.d.ts +4 -5
  163. package/lib/types/interaction_handler/InteractionHandler.d.ts.map +1 -1
  164. package/lib/types/interaction_handler/SilentHandler.d.ts +4 -2
  165. package/lib/types/interaction_handler/SilentHandler.d.ts.map +1 -1
  166. package/lib/types/naa/mapping/NestedAppAuthAdapter.d.ts.map +1 -1
  167. package/lib/types/packageMetadata.d.ts +1 -1
  168. package/lib/types/protocol/Authorize.d.ts +65 -0
  169. package/lib/types/protocol/Authorize.d.ts.map +1 -0
  170. package/lib/types/request/AuthorizationUrlRequest.d.ts +2 -4
  171. package/lib/types/request/AuthorizationUrlRequest.d.ts.map +1 -1
  172. package/lib/types/request/PopupRequest.d.ts +1 -1
  173. package/lib/types/request/PopupRequest.d.ts.map +1 -1
  174. package/lib/types/request/RedirectRequest.d.ts +1 -1
  175. package/lib/types/request/RedirectRequest.d.ts.map +1 -1
  176. package/lib/types/request/SsoSilentRequest.d.ts +1 -1
  177. package/lib/types/request/SsoSilentRequest.d.ts.map +1 -1
  178. package/lib/types/response/ResponseHandler.d.ts +3 -3
  179. package/lib/types/response/ResponseHandler.d.ts.map +1 -1
  180. package/lib/types/utils/BrowserConstants.d.ts +1 -10
  181. package/lib/types/utils/BrowserConstants.d.ts.map +1 -1
  182. package/package.json +2 -2
  183. package/src/cache/BrowserCacheManager.ts +30 -205
  184. package/src/config/Configuration.ts +14 -2
  185. package/src/controllers/NestedAppAuthController.ts +2 -0
  186. package/src/controllers/StandardController.ts +35 -24
  187. package/src/controllers/UnknownOperatingContextController.ts +2 -0
  188. package/src/crypto/BrowserCrypto.ts +91 -2
  189. package/src/error/BrowserAuthError.ts +6 -8
  190. package/src/error/BrowserAuthErrorCodes.ts +3 -1
  191. package/src/interaction_client/NativeInteractionClient.ts +11 -2
  192. package/src/interaction_client/PopupClient.ts +174 -111
  193. package/src/interaction_client/RedirectClient.ts +269 -132
  194. package/src/interaction_client/SilentAuthCodeClient.ts +2 -2
  195. package/src/interaction_client/SilentIframeClient.ts +168 -100
  196. package/src/interaction_client/StandardInteractionClient.ts +3 -43
  197. package/src/interaction_handler/InteractionHandler.ts +8 -7
  198. package/src/interaction_handler/SilentHandler.ts +31 -2
  199. package/src/naa/mapping/NestedAppAuthAdapter.ts +1 -2
  200. package/src/packageMetadata.ts +1 -1
  201. package/src/protocol/Authorize.ts +490 -0
  202. package/src/request/AuthorizationUrlRequest.ts +3 -5
  203. package/src/request/PopupRequest.ts +1 -0
  204. package/src/request/RedirectRequest.ts +1 -0
  205. package/src/request/SsoSilentRequest.ts +1 -0
  206. package/src/response/ResponseHandler.ts +3 -3
  207. package/src/utils/BrowserConstants.ts +1 -10
  208. package/dist/interaction_handler/RedirectHandler.d.ts +0 -33
  209. package/dist/interaction_handler/RedirectHandler.d.ts.map +0 -1
  210. package/dist/interaction_handler/RedirectHandler.mjs +0 -144
  211. package/dist/interaction_handler/RedirectHandler.mjs.map +0 -1
  212. package/lib/types/interaction_handler/RedirectHandler.d.ts +0 -33
  213. package/lib/types/interaction_handler/RedirectHandler.d.ts.map +0 -1
  214. package/src/interaction_handler/RedirectHandler.ts +0 -251
@@ -4,15 +4,12 @@
4
4
  */
5
5
 
6
6
  import {
7
- CommonAuthorizationCodeRequest,
8
7
  AuthorizationCodeClient,
9
8
  UrlString,
10
9
  AuthError,
11
10
  ServerTelemetryManager,
12
11
  Constants,
13
- ProtocolUtils,
14
- ServerAuthorizationCodeResponse,
15
- ThrottlingUtils,
12
+ AuthorizeResponse,
16
13
  ICrypto,
17
14
  Logger,
18
15
  IPerformanceClient,
@@ -22,6 +19,7 @@ import {
22
19
  ServerResponseType,
23
20
  UrlUtils,
24
21
  InProgressPerformanceEvent,
22
+ CommonAuthorizationUrlRequest,
25
23
  } from "@azure/msal-common/browser";
26
24
  import { StandardInteractionClient } from "./StandardInteractionClient.js";
27
25
  import {
@@ -29,7 +27,6 @@ import {
29
27
  InteractionType,
30
28
  TemporaryCacheKeys,
31
29
  } from "../utils/BrowserConstants.js";
32
- import { RedirectHandler } from "../interaction_handler/RedirectHandler.js";
33
30
  import * as BrowserUtils from "../utils/BrowserUtils.js";
34
31
  import { EndSessionRequest } from "../request/EndSessionRequest.js";
35
32
  import { EventType } from "../event/EventType.js";
@@ -39,7 +36,6 @@ import {
39
36
  BrowserAuthErrorCodes,
40
37
  } from "../error/BrowserAuthError.js";
41
38
  import { RedirectRequest } from "../request/RedirectRequest.js";
42
- import { NativeInteractionClient } from "./NativeInteractionClient.js";
43
39
  import { NativeMessageHandler } from "../broker/nativeBroker/NativeMessageHandler.js";
44
40
  import { BrowserConfiguration } from "../config/Configuration.js";
45
41
  import { BrowserCacheManager } from "../cache/BrowserCacheManager.js";
@@ -48,6 +44,9 @@ import { INavigationClient } from "../navigation/INavigationClient.js";
48
44
  import { EventError } from "../event/EventMessage.js";
49
45
  import { AuthenticationResult } from "../response/AuthenticationResult.js";
50
46
  import * as ResponseHandler from "../response/ResponseHandler.js";
47
+ import * as Authorize from "../protocol/Authorize.js";
48
+ import { generatePkceCodes } from "../crypto/PkceGenerator.js";
49
+ import { generateEarKey } from "../crypto/BrowserCrypto.js";
51
50
 
52
51
  function getNavigationType(): NavigationTimingType | undefined {
53
52
  if (
@@ -107,16 +106,13 @@ export class RedirectClient extends StandardInteractionClient {
107
106
  this.correlationId
108
107
  )(request, InteractionType.Redirect);
109
108
 
110
- this.browserStorage.updateCacheEntries(
111
- validRequest.state,
112
- validRequest.nonce,
113
- validRequest.authority,
114
- validRequest.loginHint || "",
115
- validRequest.account || null
116
- );
117
- const serverTelemetryManager = this.initializeServerTelemetryManager(
118
- ApiId.acquireTokenRedirect
119
- );
109
+ validRequest.platformBroker =
110
+ NativeMessageHandler.isPlatformBrokerAvailable(
111
+ this.config,
112
+ this.logger,
113
+ this.nativeMessageHandler,
114
+ request.authenticationScheme
115
+ );
120
116
 
121
117
  const handleBackButton = (event: PageTransitionEvent) => {
122
118
  // Clear temporary cache if the back button is clicked during the redirect flow.
@@ -124,7 +120,7 @@ export class RedirectClient extends StandardInteractionClient {
124
120
  this.logger.verbose(
125
121
  "Page was restored from back/forward cache. Clearing temporary cache."
126
122
  );
127
- this.browserStorage.cleanRequestByState(validRequest.state);
123
+ this.browserStorage.resetRequestCache();
128
124
  this.eventHandler.emitEvent(
129
125
  EventType.RESTORE_FROM_BFCACHE,
130
126
  InteractionType.Redirect
@@ -132,17 +128,71 @@ export class RedirectClient extends StandardInteractionClient {
132
128
  }
133
129
  };
134
130
 
131
+ const redirectStartPage = this.getRedirectStartPage(
132
+ request.redirectStartPage
133
+ );
134
+ this.logger.verbosePii(`Redirect start page: ${redirectStartPage}`);
135
+ // Cache start page, returns to this page after redirectUri if navigateToLoginRequestUrl is true
136
+ this.browserStorage.setTemporaryCache(
137
+ TemporaryCacheKeys.ORIGIN_URI,
138
+ redirectStartPage,
139
+ true
140
+ );
141
+
142
+ // Clear temporary cache if the back button is clicked during the redirect flow.
143
+ window.addEventListener("pageshow", handleBackButton);
144
+
135
145
  try {
136
- // Create auth code request and generate PKCE params
137
- const authCodeRequest: CommonAuthorizationCodeRequest =
138
- await invokeAsync(
139
- this.initializeAuthorizationCodeRequest.bind(this),
140
- PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest,
141
- this.logger,
142
- this.performanceClient,
143
- this.correlationId
144
- )(validRequest);
146
+ if (this.config.auth.protocolMode === ProtocolMode.EAR) {
147
+ await this.executeEarFlow(validRequest);
148
+ } else {
149
+ await this.executeCodeFlow(
150
+ validRequest,
151
+ request.onRedirectNavigate
152
+ );
153
+ }
154
+ } catch (e) {
155
+ if (e instanceof AuthError) {
156
+ e.setCorrelationId(this.correlationId);
157
+ }
158
+ window.removeEventListener("pageshow", handleBackButton);
159
+ throw e;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Executes auth code + PKCE flow
165
+ * @param request
166
+ * @returns
167
+ */
168
+ async executeCodeFlow(
169
+ request: CommonAuthorizationUrlRequest,
170
+ onRedirectNavigate?: (url: string) => boolean | void
171
+ ): Promise<void> {
172
+ const correlationId = request.correlationId;
173
+ const serverTelemetryManager = this.initializeServerTelemetryManager(
174
+ ApiId.acquireTokenRedirect
175
+ );
176
+
177
+ const pkceCodes = await invokeAsync(
178
+ generatePkceCodes,
179
+ PerformanceEvents.GeneratePkceCodes,
180
+ this.logger,
181
+ this.performanceClient,
182
+ correlationId
183
+ )(this.performanceClient, this.logger, correlationId);
184
+
185
+ const redirectRequest = {
186
+ ...request,
187
+ codeChallenge: pkceCodes.challenge,
188
+ };
189
+
190
+ this.browserStorage.cacheAuthorizeRequest(
191
+ redirectRequest,
192
+ pkceCodes.verifier
193
+ );
145
194
 
195
+ try {
146
196
  // Initialize the client
147
197
  const authClient: AuthorizationCodeClient = await invokeAsync(
148
198
  this.createAuthCodeClient.bind(this),
@@ -152,60 +202,87 @@ export class RedirectClient extends StandardInteractionClient {
152
202
  this.correlationId
153
203
  )({
154
204
  serverTelemetryManager,
155
- requestAuthority: validRequest.authority,
156
- requestAzureCloudOptions: validRequest.azureCloudOptions,
157
- requestExtraQueryParameters: validRequest.extraQueryParameters,
158
- account: validRequest.account,
205
+ requestAuthority: redirectRequest.authority,
206
+ requestAzureCloudOptions: redirectRequest.azureCloudOptions,
207
+ requestExtraQueryParameters:
208
+ redirectRequest.extraQueryParameters,
209
+ account: redirectRequest.account,
159
210
  });
160
211
 
161
- // Create redirect interaction handler.
162
- const interactionHandler = new RedirectHandler(
163
- authClient,
164
- this.browserStorage,
165
- authCodeRequest,
212
+ // Create acquire token url.
213
+ const navigateUrl = await invokeAsync(
214
+ Authorize.getAuthCodeRequestUrl,
215
+ PerformanceEvents.GetAuthCodeUrl,
216
+ this.logger,
217
+ this.performanceClient,
218
+ request.correlationId
219
+ )(
220
+ this.config,
221
+ authClient.authority,
222
+ redirectRequest,
166
223
  this.logger,
167
224
  this.performanceClient
168
225
  );
169
-
170
- // Create acquire token url.
171
- const navigateUrl = await authClient.getAuthCodeUrl({
172
- ...validRequest,
173
- platformBroker: NativeMessageHandler.isPlatformBrokerAvailable(
174
- this.config,
175
- this.logger,
176
- this.nativeMessageHandler,
177
- request.authenticationScheme
178
- ),
179
- });
180
-
181
- const redirectStartPage = this.getRedirectStartPage(
182
- request.redirectStartPage
183
- );
184
- this.logger.verbosePii(`Redirect start page: ${redirectStartPage}`);
185
-
186
- // Clear temporary cache if the back button is clicked during the redirect flow.
187
- window.addEventListener("pageshow", handleBackButton);
188
-
189
226
  // Show the UI once the url has been created. Response will come back in the hash, which will be handled in the handleRedirectCallback function.
190
- return await interactionHandler.initiateAuthRequest(navigateUrl, {
191
- navigationClient: this.navigationClient,
192
- redirectTimeout: this.config.system.redirectNavigationTimeout,
193
- redirectStartPage: redirectStartPage,
194
- onRedirectNavigate:
195
- request.onRedirectNavigate ||
196
- this.config.auth.onRedirectNavigate,
197
- });
227
+ return await this.initiateAuthRequest(
228
+ navigateUrl,
229
+ onRedirectNavigate
230
+ );
198
231
  } catch (e) {
199
232
  if (e instanceof AuthError) {
200
233
  e.setCorrelationId(this.correlationId);
201
234
  serverTelemetryManager.cacheFailedRequest(e);
202
235
  }
203
- window.removeEventListener("pageshow", handleBackButton);
204
- this.browserStorage.cleanRequestByState(validRequest.state);
205
236
  throw e;
206
237
  }
207
238
  }
208
239
 
240
+ /**
241
+ * Executes EAR flow
242
+ * @param request
243
+ */
244
+ async executeEarFlow(
245
+ request: CommonAuthorizationUrlRequest
246
+ ): Promise<void> {
247
+ const correlationId = request.correlationId;
248
+ // Get the frame handle for the silent request
249
+ const discoveredAuthority = await invokeAsync(
250
+ this.getDiscoveredAuthority.bind(this),
251
+ PerformanceEvents.StandardInteractionClientGetDiscoveredAuthority,
252
+ this.logger,
253
+ this.performanceClient,
254
+ correlationId
255
+ )({
256
+ requestAuthority: request.authority,
257
+ requestAzureCloudOptions: request.azureCloudOptions,
258
+ requestExtraQueryParameters: request.extraQueryParameters,
259
+ account: request.account,
260
+ });
261
+
262
+ const earJwk = await invokeAsync(
263
+ generateEarKey,
264
+ PerformanceEvents.GenerateEarKey,
265
+ this.logger,
266
+ this.performanceClient,
267
+ correlationId
268
+ )();
269
+ const redirectRequest = {
270
+ ...request,
271
+ earJwk: earJwk,
272
+ };
273
+ this.browserStorage.cacheAuthorizeRequest(redirectRequest);
274
+
275
+ const form = await Authorize.getEARForm(
276
+ document,
277
+ this.config,
278
+ discoveredAuthority,
279
+ redirectRequest,
280
+ this.logger,
281
+ this.performanceClient
282
+ );
283
+ form.submit();
284
+ }
285
+
209
286
  /**
210
287
  * Checks if navigateToLoginRequestUrl is set, and:
211
288
  * - if true, performs logic to cache and navigate
@@ -215,6 +292,8 @@ export class RedirectClient extends StandardInteractionClient {
215
292
  */
216
293
  async handleRedirectPromise(
217
294
  hash: string = "",
295
+ request: CommonAuthorizationUrlRequest,
296
+ pkceVerifier: string,
218
297
  parentMeasurement: InProgressPerformanceEvent
219
298
  ): Promise<AuthenticationResult | null> {
220
299
  const serverTelemetryManager = this.initializeServerTelemetryManager(
@@ -222,12 +301,6 @@ export class RedirectClient extends StandardInteractionClient {
222
301
  );
223
302
 
224
303
  try {
225
- if (!this.browserStorage.isInteractionInProgress(true)) {
226
- this.logger.info(
227
- "handleRedirectPromise called but there is no interaction in progress, returning null."
228
- );
229
- return null;
230
- }
231
304
  const [serverParams, responseString] = this.getRedirectResponse(
232
305
  hash || ""
233
306
  );
@@ -236,9 +309,7 @@ export class RedirectClient extends StandardInteractionClient {
236
309
  this.logger.info(
237
310
  "handleRedirectPromise did not detect a response as a result of a redirect. Cleaning temporary cache."
238
311
  );
239
- this.browserStorage.cleanRequestByInteractionType(
240
- InteractionType.Redirect
241
- );
312
+ this.browserStorage.resetRequestCache();
242
313
 
243
314
  // Do not instrument "no_server_response" if user clicked back button
244
315
  if (getNavigationType() !== "back_forward") {
@@ -279,6 +350,8 @@ export class RedirectClient extends StandardInteractionClient {
279
350
 
280
351
  const handleHashResult = await this.handleResponse(
281
352
  serverParams,
353
+ request,
354
+ pkceVerifier,
282
355
  serverTelemetryManager
283
356
  );
284
357
 
@@ -289,6 +362,8 @@ export class RedirectClient extends StandardInteractionClient {
289
362
  );
290
363
  return await this.handleResponse(
291
364
  serverParams,
365
+ request,
366
+ pkceVerifier,
292
367
  serverTelemetryManager
293
368
  );
294
369
  } else if (
@@ -348,6 +423,8 @@ export class RedirectClient extends StandardInteractionClient {
348
423
  if (!processHashOnRedirect) {
349
424
  return await this.handleResponse(
350
425
  serverParams,
426
+ request,
427
+ pkceVerifier,
351
428
  serverTelemetryManager
352
429
  );
353
430
  }
@@ -359,9 +436,6 @@ export class RedirectClient extends StandardInteractionClient {
359
436
  (e as AuthError).setCorrelationId(this.correlationId);
360
437
  serverTelemetryManager.cacheFailedRequest(e);
361
438
  }
362
- this.browserStorage.cleanRequestByInteractionType(
363
- InteractionType.Redirect
364
- );
365
439
  throw e;
366
440
  }
367
441
  }
@@ -373,7 +447,7 @@ export class RedirectClient extends StandardInteractionClient {
373
447
  */
374
448
  protected getRedirectResponse(
375
449
  userProvidedResponse: string
376
- ): [ServerAuthorizationCodeResponse | null, string] {
450
+ ): [AuthorizeResponse | null, string] {
377
451
  this.logger.verbose("getRedirectResponseHash called");
378
452
  // Get current location hash from window or cache.
379
453
  let responseString = userProvidedResponse;
@@ -439,7 +513,9 @@ export class RedirectClient extends StandardInteractionClient {
439
513
  * @param state
440
514
  */
441
515
  protected async handleResponse(
442
- serverParams: ServerAuthorizationCodeResponse,
516
+ serverParams: AuthorizeResponse,
517
+ request: CommonAuthorizationUrlRequest,
518
+ codeVerifier: string,
443
519
  serverTelemetryManager: ServerTelemetryManager
444
520
  ): Promise<AuthenticationResult> {
445
521
  const state = serverParams.state;
@@ -447,52 +523,37 @@ export class RedirectClient extends StandardInteractionClient {
447
523
  throw createBrowserAuthError(BrowserAuthErrorCodes.noStateInHash);
448
524
  }
449
525
 
450
- const cachedRequest = this.browserStorage.getCachedRequest(state);
451
- this.logger.verbose("handleResponse called, retrieved cached request");
452
-
453
- if (serverParams.accountId) {
454
- this.logger.verbose(
455
- "Account id found in hash, calling WAM for token"
456
- );
457
- if (!this.nativeMessageHandler) {
458
- throw createBrowserAuthError(
459
- BrowserAuthErrorCodes.nativeConnectionNotEstablished
460
- );
461
- }
462
- const nativeInteractionClient = new NativeInteractionClient(
526
+ if (serverParams.ear_jwe) {
527
+ const discoveredAuthority = await invokeAsync(
528
+ this.getDiscoveredAuthority.bind(this),
529
+ PerformanceEvents.StandardInteractionClientGetDiscoveredAuthority,
530
+ this.logger,
531
+ this.performanceClient,
532
+ request.correlationId
533
+ )({
534
+ requestAuthority: request.authority,
535
+ requestAzureCloudOptions: request.azureCloudOptions,
536
+ requestExtraQueryParameters: request.extraQueryParameters,
537
+ account: request.account,
538
+ });
539
+ return invokeAsync(
540
+ Authorize.handleResponseEAR,
541
+ PerformanceEvents.HandleResponseEar,
542
+ this.logger,
543
+ this.performanceClient,
544
+ request.correlationId
545
+ )(
546
+ request,
547
+ serverParams,
548
+ ApiId.acquireTokenRedirect,
463
549
  this.config,
550
+ discoveredAuthority,
464
551
  this.browserStorage,
465
- this.browserCrypto,
466
- this.logger,
552
+ this.nativeStorage,
467
553
  this.eventHandler,
468
- this.navigationClient,
469
- ApiId.acquireTokenPopup,
554
+ this.logger,
470
555
  this.performanceClient,
471
- this.nativeMessageHandler,
472
- serverParams.accountId,
473
- this.nativeStorage,
474
- cachedRequest.correlationId
475
- );
476
- const { userRequestState } = ProtocolUtils.parseRequestState(
477
- this.browserCrypto,
478
- state
479
- );
480
- return nativeInteractionClient
481
- .acquireToken({
482
- ...cachedRequest,
483
- state: userRequestState,
484
- prompt: undefined, // Server should handle the prompt, ideally native broker can do this part silently
485
- })
486
- .finally(() => {
487
- this.browserStorage.cleanRequestByState(state);
488
- });
489
- }
490
-
491
- // Hash contains known properties - handle and return in callback
492
- const currentAuthority = this.browserStorage.getCachedAuthority(state);
493
- if (!currentAuthority) {
494
- throw createBrowserAuthError(
495
- BrowserAuthErrorCodes.noCachedAuthorityError
556
+ this.nativeMessageHandler
496
557
  );
497
558
  }
498
559
 
@@ -502,21 +563,97 @@ export class RedirectClient extends StandardInteractionClient {
502
563
  this.logger,
503
564
  this.performanceClient,
504
565
  this.correlationId
505
- )({ serverTelemetryManager, requestAuthority: currentAuthority });
506
-
507
- ThrottlingUtils.removeThrottle(
508
- this.browserStorage,
509
- this.config.auth.clientId,
510
- cachedRequest
511
- );
512
- const interactionHandler = new RedirectHandler(
566
+ )({ serverTelemetryManager, requestAuthority: request.authority });
567
+ return invokeAsync(
568
+ Authorize.handleResponseCode,
569
+ PerformanceEvents.HandleResponseCode,
570
+ this.logger,
571
+ this.performanceClient,
572
+ request.correlationId
573
+ )(
574
+ request,
575
+ serverParams,
576
+ codeVerifier,
577
+ ApiId.acquireTokenRedirect,
578
+ this.config,
513
579
  authClient,
514
580
  this.browserStorage,
515
- cachedRequest,
581
+ this.nativeStorage,
582
+ this.eventHandler,
516
583
  this.logger,
517
- this.performanceClient
584
+ this.performanceClient,
585
+ this.nativeMessageHandler
518
586
  );
519
- return interactionHandler.handleCodeResponse(serverParams, state);
587
+ }
588
+
589
+ /**
590
+ * Redirects window to given URL.
591
+ * @param urlNavigate
592
+ * @param onRedirectNavigateRequest - onRedirectNavigate callback provided on the request
593
+ */
594
+ async initiateAuthRequest(
595
+ requestUrl: string,
596
+ onRedirectNavigateRequest?: (url: string) => boolean | void
597
+ ): Promise<void> {
598
+ this.logger.verbose("RedirectHandler.initiateAuthRequest called");
599
+ // Navigate if valid URL
600
+ if (requestUrl) {
601
+ this.logger.infoPii(
602
+ `RedirectHandler.initiateAuthRequest: Navigate to: ${requestUrl}`
603
+ );
604
+ const navigationOptions: NavigationOptions = {
605
+ apiId: ApiId.acquireTokenRedirect,
606
+ timeout: this.config.system.redirectNavigationTimeout,
607
+ noHistory: false,
608
+ };
609
+
610
+ const onRedirectNavigate =
611
+ onRedirectNavigateRequest ||
612
+ this.config.auth.onRedirectNavigate;
613
+
614
+ // If onRedirectNavigate is implemented, invoke it and provide requestUrl
615
+ if (typeof onRedirectNavigate === "function") {
616
+ this.logger.verbose(
617
+ "RedirectHandler.initiateAuthRequest: Invoking onRedirectNavigate callback"
618
+ );
619
+ const navigate = onRedirectNavigate(requestUrl);
620
+
621
+ // Returning false from onRedirectNavigate will stop navigation
622
+ if (navigate !== false) {
623
+ this.logger.verbose(
624
+ "RedirectHandler.initiateAuthRequest: onRedirectNavigate did not return false, navigating"
625
+ );
626
+ await this.navigationClient.navigateExternal(
627
+ requestUrl,
628
+ navigationOptions
629
+ );
630
+ return;
631
+ } else {
632
+ this.logger.verbose(
633
+ "RedirectHandler.initiateAuthRequest: onRedirectNavigate returned false, stopping navigation"
634
+ );
635
+ return;
636
+ }
637
+ } else {
638
+ // Navigate window to request URL
639
+ this.logger.verbose(
640
+ "RedirectHandler.initiateAuthRequest: Navigating window to navigate url"
641
+ );
642
+ await this.navigationClient.navigateExternal(
643
+ requestUrl,
644
+ navigationOptions
645
+ );
646
+ return;
647
+ }
648
+ } else {
649
+ // Throw error if request URL is empty.
650
+ this.logger.info(
651
+ "RedirectHandler.initiateAuthRequest: Navigate url is empty"
652
+ );
653
+ throw createBrowserAuthError(
654
+ BrowserAuthErrorCodes.emptyNavigateUri
655
+ );
656
+ }
520
657
  }
521
658
 
522
659
  /**
@@ -11,9 +11,9 @@ import {
11
11
  IPerformanceClient,
12
12
  PerformanceEvents,
13
13
  invokeAsync,
14
+ CommonAuthorizationUrlRequest,
14
15
  } from "@azure/msal-common/browser";
15
16
  import { StandardInteractionClient } from "./StandardInteractionClient.js";
16
- import { AuthorizationUrlRequest } from "../request/AuthorizationUrlRequest.js";
17
17
  import { BrowserConfiguration } from "../config/Configuration.js";
18
18
  import { BrowserCacheManager } from "../cache/BrowserCacheManager.js";
19
19
  import { EventHandler } from "../event/EventHandler.js";
@@ -73,7 +73,7 @@ export class SilentAuthCodeClient extends StandardInteractionClient {
73
73
  }
74
74
 
75
75
  // Create silent request
76
- const silentRequest: AuthorizationUrlRequest = await invokeAsync(
76
+ const silentRequest: CommonAuthorizationUrlRequest = await invokeAsync(
77
77
  this.initializeAuthorizationRequest.bind(this),
78
78
  PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest,
79
79
  this.logger,