@azure/msal-browser 3.0.1 → 3.1.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 (257) hide show
  1. package/README.md +5 -5
  2. package/dist/app/IPublicClientApplication.d.ts +6 -2
  3. package/dist/app/IPublicClientApplication.d.ts.map +1 -1
  4. package/dist/app/IPublicClientApplication.mjs +4 -1
  5. package/dist/app/IPublicClientApplication.mjs.map +1 -1
  6. package/dist/app/PublicClientApplication.d.ts +11 -3
  7. package/dist/app/PublicClientApplication.d.ts.map +1 -1
  8. package/dist/app/PublicClientApplication.mjs +10 -2
  9. package/dist/app/PublicClientApplication.mjs.map +1 -1
  10. package/dist/broker/nativeBroker/NativeMessageHandler.d.ts.map +1 -1
  11. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +5 -4
  12. package/dist/broker/nativeBroker/NativeMessageHandler.mjs.map +1 -1
  13. package/dist/cache/AsyncMemoryStorage.mjs +4 -3
  14. package/dist/cache/AsyncMemoryStorage.mjs.map +1 -1
  15. package/dist/cache/BrowserCacheManager.d.ts +13 -3
  16. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  17. package/dist/cache/BrowserCacheManager.mjs +54 -26
  18. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  19. package/dist/cache/BrowserStorage.mjs +1 -1
  20. package/dist/cache/BrowserStorage.mjs.map +1 -1
  21. package/dist/cache/CryptoKeyStore.mjs +1 -1
  22. package/dist/cache/CryptoKeyStore.mjs.map +1 -1
  23. package/dist/cache/DatabaseStorage.d.ts.map +1 -1
  24. package/dist/cache/DatabaseStorage.mjs +9 -8
  25. package/dist/cache/DatabaseStorage.mjs.map +1 -1
  26. package/dist/cache/MemoryStorage.mjs +1 -1
  27. package/dist/cache/MemoryStorage.mjs.map +1 -1
  28. package/dist/cache/TokenCache.d.ts.map +1 -1
  29. package/dist/cache/TokenCache.mjs +30 -30
  30. package/dist/cache/TokenCache.mjs.map +1 -1
  31. package/dist/config/Configuration.d.ts +3 -0
  32. package/dist/config/Configuration.d.ts.map +1 -1
  33. package/dist/config/Configuration.mjs +7 -11
  34. package/dist/config/Configuration.mjs.map +1 -1
  35. package/dist/controllers/ControllerFactory.mjs +1 -1
  36. package/dist/controllers/ControllerFactory.mjs.map +1 -1
  37. package/dist/controllers/IController.d.ts +11 -18
  38. package/dist/controllers/IController.d.ts.map +1 -1
  39. package/dist/controllers/StandardController.d.ts +7 -26
  40. package/dist/controllers/StandardController.d.ts.map +1 -1
  41. package/dist/controllers/StandardController.mjs +28 -52
  42. package/dist/controllers/StandardController.mjs.map +1 -1
  43. package/dist/crypto/BrowserCrypto.d.ts.map +1 -1
  44. package/dist/crypto/BrowserCrypto.mjs +4 -3
  45. package/dist/crypto/BrowserCrypto.mjs.map +1 -1
  46. package/dist/crypto/CryptoOps.d.ts +0 -3
  47. package/dist/crypto/CryptoOps.d.ts.map +1 -1
  48. package/dist/crypto/CryptoOps.mjs +14 -17
  49. package/dist/crypto/CryptoOps.mjs.map +1 -1
  50. package/dist/crypto/ModernBrowserCrypto.mjs +1 -1
  51. package/dist/crypto/ModernBrowserCrypto.mjs.map +1 -1
  52. package/dist/crypto/PkceGenerator.d.ts +0 -1
  53. package/dist/crypto/PkceGenerator.d.ts.map +1 -1
  54. package/dist/crypto/PkceGenerator.mjs +8 -8
  55. package/dist/crypto/PkceGenerator.mjs.map +1 -1
  56. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  57. package/dist/crypto/SignedHttpRequest.mjs.map +1 -1
  58. package/dist/encode/Base64Decode.d.ts +6 -19
  59. package/dist/encode/Base64Decode.d.ts.map +1 -1
  60. package/dist/encode/Base64Decode.mjs +17 -70
  61. package/dist/encode/Base64Decode.mjs.map +1 -1
  62. package/dist/encode/Base64Encode.d.ts +15 -27
  63. package/dist/encode/Base64Encode.d.ts.map +1 -1
  64. package/dist/encode/Base64Encode.mjs +36 -75
  65. package/dist/encode/Base64Encode.mjs.map +1 -1
  66. package/dist/error/BrowserAuthError.d.ts +54 -195
  67. package/dist/error/BrowserAuthError.d.ts.map +1 -1
  68. package/dist/error/BrowserAuthError.mjs +150 -381
  69. package/dist/error/BrowserAuthError.mjs.map +1 -1
  70. package/dist/error/BrowserAuthErrorCodes.d.ts +45 -0
  71. package/dist/error/BrowserAuthErrorCodes.d.ts.map +1 -0
  72. package/dist/error/BrowserAuthErrorCodes.mjs +53 -0
  73. package/dist/error/BrowserAuthErrorCodes.mjs.map +1 -0
  74. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  75. package/dist/error/BrowserConfigurationAuthError.mjs.map +1 -1
  76. package/dist/error/NativeAuthError.d.ts.map +1 -1
  77. package/dist/error/NativeAuthError.mjs +5 -4
  78. package/dist/error/NativeAuthError.mjs.map +1 -1
  79. package/dist/event/EventHandler.mjs +1 -1
  80. package/dist/event/EventHandler.mjs.map +1 -1
  81. package/dist/event/EventMessage.mjs +1 -1
  82. package/dist/event/EventMessage.mjs.map +1 -1
  83. package/dist/event/EventType.mjs +1 -1
  84. package/dist/event/EventType.mjs.map +1 -1
  85. package/dist/index.d.ts +9 -6
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.mjs +5 -3
  88. package/dist/index.mjs.map +1 -1
  89. package/dist/interaction_client/BaseInteractionClient.d.ts +2 -1
  90. package/dist/interaction_client/BaseInteractionClient.d.ts.map +1 -1
  91. package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
  92. package/dist/interaction_client/BaseInteractionClient.mjs.map +1 -1
  93. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  94. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs.map +1 -1
  95. package/dist/interaction_client/NativeInteractionClient.d.ts +4 -10
  96. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  97. package/dist/interaction_client/NativeInteractionClient.mjs +22 -30
  98. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  99. package/dist/interaction_client/PopupClient.d.ts.map +1 -1
  100. package/dist/interaction_client/PopupClient.mjs +16 -15
  101. package/dist/interaction_client/PopupClient.mjs.map +1 -1
  102. package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
  103. package/dist/interaction_client/RedirectClient.mjs +7 -6
  104. package/dist/interaction_client/RedirectClient.mjs.map +1 -1
  105. package/dist/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
  106. package/dist/interaction_client/SilentAuthCodeClient.mjs +5 -4
  107. package/dist/interaction_client/SilentAuthCodeClient.mjs.map +1 -1
  108. package/dist/interaction_client/SilentCacheClient.d.ts +4 -2
  109. package/dist/interaction_client/SilentCacheClient.d.ts.map +1 -1
  110. package/dist/interaction_client/SilentCacheClient.mjs +10 -8
  111. package/dist/interaction_client/SilentCacheClient.mjs.map +1 -1
  112. package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
  113. package/dist/interaction_client/SilentIframeClient.mjs +20 -47
  114. package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
  115. package/dist/interaction_client/SilentRefreshClient.d.ts.map +1 -1
  116. package/dist/interaction_client/SilentRefreshClient.mjs +4 -3
  117. package/dist/interaction_client/SilentRefreshClient.mjs.map +1 -1
  118. package/dist/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  119. package/dist/interaction_client/StandardInteractionClient.mjs +8 -7
  120. package/dist/interaction_client/StandardInteractionClient.mjs.map +1 -1
  121. package/dist/interaction_handler/InteractionHandler.d.ts.map +1 -1
  122. package/dist/interaction_handler/InteractionHandler.mjs +9 -9
  123. package/dist/interaction_handler/InteractionHandler.mjs.map +1 -1
  124. package/dist/interaction_handler/RedirectHandler.d.ts.map +1 -1
  125. package/dist/interaction_handler/RedirectHandler.mjs +11 -10
  126. package/dist/interaction_handler/RedirectHandler.mjs.map +1 -1
  127. package/dist/interaction_handler/SilentHandler.d.ts.map +1 -1
  128. package/dist/interaction_handler/SilentHandler.mjs +10 -9
  129. package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
  130. package/dist/navigation/NavigationClient.mjs +1 -1
  131. package/dist/navigation/NavigationClient.mjs.map +1 -1
  132. package/dist/network/FetchClient.d.ts.map +1 -1
  133. package/dist/network/FetchClient.mjs +9 -8
  134. package/dist/network/FetchClient.mjs.map +1 -1
  135. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  136. package/dist/operatingcontext/BaseOperatingContext.mjs.map +1 -1
  137. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  138. package/dist/operatingcontext/StandardOperatingContext.mjs.map +1 -1
  139. package/dist/operatingcontext/TeamsAppOperatingContext.mjs +1 -1
  140. package/dist/operatingcontext/TeamsAppOperatingContext.mjs.map +1 -1
  141. package/dist/packageMetadata.d.ts +1 -1
  142. package/dist/packageMetadata.mjs +2 -2
  143. package/dist/packageMetadata.mjs.map +1 -1
  144. package/dist/request/ClearCacheRequest.d.ts +11 -0
  145. package/dist/request/ClearCacheRequest.d.ts.map +1 -0
  146. package/dist/telemetry/BrowserPerformanceClient.d.ts +2 -4
  147. package/dist/telemetry/BrowserPerformanceClient.d.ts.map +1 -1
  148. package/dist/telemetry/BrowserPerformanceClient.mjs +2 -6
  149. package/dist/telemetry/BrowserPerformanceClient.mjs.map +1 -1
  150. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  151. package/dist/telemetry/BrowserPerformanceMeasurement.mjs.map +1 -1
  152. package/dist/utils/BrowserConstants.mjs +1 -1
  153. package/dist/utils/BrowserConstants.mjs.map +1 -1
  154. package/dist/utils/BrowserProtocolUtils.d.ts.map +1 -1
  155. package/dist/utils/BrowserProtocolUtils.mjs +3 -3
  156. package/dist/utils/BrowserProtocolUtils.mjs.map +1 -1
  157. package/dist/utils/BrowserStringUtils.mjs +1 -1
  158. package/dist/utils/BrowserStringUtils.mjs.map +1 -1
  159. package/dist/utils/BrowserUtils.d.ts +0 -9
  160. package/dist/utils/BrowserUtils.d.ts.map +1 -1
  161. package/dist/utils/BrowserUtils.mjs +8 -33
  162. package/dist/utils/BrowserUtils.mjs.map +1 -1
  163. package/lib/msal-browser.cjs +6601 -7104
  164. package/lib/msal-browser.cjs.map +1 -1
  165. package/lib/msal-browser.js +6601 -7104
  166. package/lib/msal-browser.js.map +1 -1
  167. package/lib/msal-browser.min.js +65 -62
  168. package/package.json +7 -5
  169. package/src/app/IPublicClientApplication.ts +199 -0
  170. package/src/app/PublicClientApplication.ts +405 -0
  171. package/src/broker/nativeBroker/NativeMessageHandler.ts +419 -0
  172. package/src/broker/nativeBroker/NativeRequest.ts +52 -0
  173. package/src/broker/nativeBroker/NativeResponse.ts +56 -0
  174. package/src/cache/AsyncMemoryStorage.ts +158 -0
  175. package/src/cache/BrowserCacheManager.ts +1994 -0
  176. package/src/cache/BrowserStorage.ts +54 -0
  177. package/src/cache/CryptoKeyStore.ts +63 -0
  178. package/src/cache/DatabaseStorage.ts +287 -0
  179. package/src/cache/IAsyncMemoryStorage.ts +36 -0
  180. package/src/cache/ITokenCache.ts +21 -0
  181. package/src/cache/IWindowStorage.ts +36 -0
  182. package/src/cache/MemoryStorage.ts +42 -0
  183. package/src/cache/TokenCache.ts +484 -0
  184. package/src/config/Configuration.ts +375 -0
  185. package/src/controllers/ControllerFactory.ts +55 -0
  186. package/src/controllers/IController.ts +131 -0
  187. package/src/controllers/StandardController.ts +2107 -0
  188. package/src/crypto/BrowserCrypto.ts +135 -0
  189. package/src/crypto/CryptoOps.ts +247 -0
  190. package/src/crypto/ISubtleCrypto.ts +30 -0
  191. package/src/crypto/ModernBrowserCrypto.ts +69 -0
  192. package/src/crypto/PkceGenerator.ts +76 -0
  193. package/src/crypto/SignedHttpRequest.ts +76 -0
  194. package/src/encode/Base64Decode.ts +26 -0
  195. package/src/encode/Base64Encode.ts +52 -0
  196. package/src/error/BrowserAuthError.ts +340 -0
  197. package/src/error/BrowserAuthErrorCodes.ts +56 -0
  198. package/src/error/BrowserConfigurationAuthError.ts +133 -0
  199. package/src/error/NativeAuthError.ts +141 -0
  200. package/src/event/EventHandler.ts +176 -0
  201. package/src/event/EventMessage.ts +125 -0
  202. package/src/event/EventType.ts +33 -0
  203. package/src/index.ts +152 -0
  204. package/src/interaction_client/BaseInteractionClient.ts +301 -0
  205. package/src/interaction_client/HybridSpaAuthorizationCodeClient.ts +16 -0
  206. package/src/interaction_client/NativeInteractionClient.ts +907 -0
  207. package/src/interaction_client/PopupClient.ts +926 -0
  208. package/src/interaction_client/RedirectClient.ts +616 -0
  209. package/src/interaction_client/SilentAuthCodeClient.ts +163 -0
  210. package/src/interaction_client/SilentCacheClient.ts +133 -0
  211. package/src/interaction_client/SilentIframeClient.ts +301 -0
  212. package/src/interaction_client/SilentRefreshClient.ts +120 -0
  213. package/src/interaction_client/StandardInteractionClient.ts +481 -0
  214. package/src/interaction_handler/InteractionHandler.ts +246 -0
  215. package/src/interaction_handler/RedirectHandler.ts +225 -0
  216. package/src/interaction_handler/SilentHandler.ts +266 -0
  217. package/src/navigation/INavigationClient.ts +23 -0
  218. package/src/navigation/NavigationClient.ts +55 -0
  219. package/src/navigation/NavigationOptions.ts +18 -0
  220. package/src/network/FetchClient.ts +130 -0
  221. package/src/operatingcontext/BaseOperatingContext.ts +82 -0
  222. package/src/operatingcontext/StandardOperatingContext.ts +49 -0
  223. package/src/operatingcontext/TeamsAppOperatingContext.ts +48 -0
  224. package/src/packageMetadata.ts +3 -0
  225. package/src/request/AuthorizationCodeRequest.ts +19 -0
  226. package/src/request/AuthorizationUrlRequest.ts +17 -0
  227. package/src/request/ClearCacheRequest.ts +16 -0
  228. package/src/request/EndSessionPopupRequest.ts +26 -0
  229. package/src/request/EndSessionRequest.ts +23 -0
  230. package/src/request/PopupRequest.ts +51 -0
  231. package/src/request/PopupWindowAttributes.ts +22 -0
  232. package/src/request/RedirectRequest.ts +51 -0
  233. package/src/request/SilentRequest.ts +49 -0
  234. package/src/request/SsoSilentRequest.ts +44 -0
  235. package/src/response/AuthenticationResult.ts +13 -0
  236. package/src/telemetry/BrowserPerformanceClient.ts +226 -0
  237. package/src/telemetry/BrowserPerformanceMeasurement.ts +144 -0
  238. package/src/utils/BrowserConstants.ts +241 -0
  239. package/src/utils/BrowserProtocolUtils.ts +57 -0
  240. package/src/utils/BrowserStringUtils.ts +143 -0
  241. package/src/utils/BrowserUtils.ts +156 -0
  242. package/dist/crypto/GuidGenerator.d.ts +0 -13
  243. package/dist/crypto/GuidGenerator.d.ts.map +0 -1
  244. package/dist/crypto/GuidGenerator.mjs +0 -104
  245. package/dist/crypto/GuidGenerator.mjs.map +0 -1
  246. package/dist/internals.d.ts +0 -23
  247. package/dist/internals.d.ts.map +0 -1
  248. package/dist/internals.mjs +0 -28
  249. package/dist/internals.mjs.map +0 -1
  250. package/dist/network/XhrClient.d.ts +0 -41
  251. package/dist/network/XhrClient.d.ts.map +0 -1
  252. package/dist/network/XhrClient.mjs +0 -125
  253. package/dist/network/XhrClient.mjs.map +0 -1
  254. package/dist/utils/MathUtils.d.ts +0 -12
  255. package/dist/utils/MathUtils.d.ts.map +0 -1
  256. package/dist/utils/MathUtils.mjs +0 -26
  257. package/dist/utils/MathUtils.mjs.map +0 -1
@@ -0,0 +1,246 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ AuthorizationCodePayload,
8
+ CommonAuthorizationCodeRequest,
9
+ AuthorizationCodeClient,
10
+ AuthorityFactory,
11
+ Authority,
12
+ INetworkModule,
13
+ ClientAuthError,
14
+ CcsCredential,
15
+ Logger,
16
+ ServerError,
17
+ IPerformanceClient,
18
+ PerformanceEvents,
19
+ invokeAsync,
20
+ } from "@azure/msal-common";
21
+
22
+ import { BrowserCacheManager } from "../cache/BrowserCacheManager";
23
+ import {
24
+ createBrowserAuthError,
25
+ BrowserAuthErrorCodes,
26
+ } from "../error/BrowserAuthError";
27
+ import { TemporaryCacheKeys } from "../utils/BrowserConstants";
28
+ import { AuthenticationResult } from "../response/AuthenticationResult";
29
+
30
+ export type InteractionParams = {};
31
+
32
+ /**
33
+ * Abstract class which defines operations for a browser interaction handling class.
34
+ */
35
+ export class InteractionHandler {
36
+ protected authModule: AuthorizationCodeClient;
37
+ protected browserStorage: BrowserCacheManager;
38
+ protected authCodeRequest: CommonAuthorizationCodeRequest;
39
+ protected logger: Logger;
40
+ protected performanceClient: IPerformanceClient;
41
+
42
+ constructor(
43
+ authCodeModule: AuthorizationCodeClient,
44
+ storageImpl: BrowserCacheManager,
45
+ authCodeRequest: CommonAuthorizationCodeRequest,
46
+ logger: Logger,
47
+ performanceClient: IPerformanceClient
48
+ ) {
49
+ this.authModule = authCodeModule;
50
+ this.browserStorage = storageImpl;
51
+ this.authCodeRequest = authCodeRequest;
52
+ this.logger = logger;
53
+ this.performanceClient = performanceClient;
54
+ }
55
+
56
+ /**
57
+ * Function to handle response parameters from hash.
58
+ * @param locationHash
59
+ */
60
+ async handleCodeResponseFromHash(
61
+ locationHash: string,
62
+ state: string,
63
+ authority: Authority,
64
+ networkModule: INetworkModule
65
+ ): Promise<AuthenticationResult> {
66
+ this.performanceClient.addQueueMeasurement(
67
+ PerformanceEvents.HandleCodeResponseFromHash,
68
+ this.authCodeRequest.correlationId
69
+ );
70
+ this.logger.verbose("InteractionHandler.handleCodeResponse called");
71
+ // Check that location hash isn't empty.
72
+ if (!locationHash) {
73
+ throw createBrowserAuthError(BrowserAuthErrorCodes.hashEmptyError);
74
+ }
75
+
76
+ // Handle code response.
77
+ const stateKey = this.browserStorage.generateStateKey(state);
78
+ const requestState = this.browserStorage.getTemporaryCache(stateKey);
79
+ if (!requestState) {
80
+ throw ClientAuthError.createStateNotFoundError("Cached State");
81
+ }
82
+
83
+ let authCodeResponse;
84
+ try {
85
+ authCodeResponse = this.authModule.handleFragmentResponse(
86
+ locationHash,
87
+ requestState
88
+ );
89
+ } catch (e) {
90
+ if (
91
+ e instanceof ServerError &&
92
+ e.subError === BrowserAuthErrorCodes.userCancelled
93
+ ) {
94
+ // Translate server error caused by user closing native prompt to corresponding first class MSAL error
95
+ throw createBrowserAuthError(
96
+ BrowserAuthErrorCodes.userCancelled
97
+ );
98
+ } else {
99
+ throw e;
100
+ }
101
+ }
102
+
103
+ this.performanceClient.setPreQueueTime(
104
+ PerformanceEvents.HandleCodeResponseFromServer,
105
+ this.authCodeRequest.correlationId
106
+ );
107
+ return this.handleCodeResponseFromServer(
108
+ authCodeResponse,
109
+ state,
110
+ authority,
111
+ networkModule
112
+ );
113
+ }
114
+
115
+ /**
116
+ * Process auth code response from AAD
117
+ * @param authCodeResponse
118
+ * @param state
119
+ * @param authority
120
+ * @param networkModule
121
+ * @returns
122
+ */
123
+ async handleCodeResponseFromServer(
124
+ authCodeResponse: AuthorizationCodePayload,
125
+ state: string,
126
+ authority: Authority,
127
+ networkModule: INetworkModule,
128
+ validateNonce: boolean = true
129
+ ): Promise<AuthenticationResult> {
130
+ this.performanceClient.addQueueMeasurement(
131
+ PerformanceEvents.HandleCodeResponseFromServer,
132
+ this.authCodeRequest.correlationId
133
+ );
134
+ this.logger.trace(
135
+ "InteractionHandler.handleCodeResponseFromServer called"
136
+ );
137
+
138
+ // Handle code response.
139
+ const stateKey = this.browserStorage.generateStateKey(state);
140
+ const requestState = this.browserStorage.getTemporaryCache(stateKey);
141
+ if (!requestState) {
142
+ throw ClientAuthError.createStateNotFoundError("Cached State");
143
+ }
144
+
145
+ // Get cached items
146
+ const nonceKey = this.browserStorage.generateNonceKey(requestState);
147
+ const cachedNonce = this.browserStorage.getTemporaryCache(nonceKey);
148
+
149
+ // Assign code to request
150
+ this.authCodeRequest.code = authCodeResponse.code;
151
+
152
+ // Check for new cloud instance
153
+ if (authCodeResponse.cloud_instance_host_name) {
154
+ this.performanceClient.setPreQueueTime(
155
+ PerformanceEvents.UpdateTokenEndpointAuthority,
156
+ this.authCodeRequest.correlationId
157
+ );
158
+ await this.updateTokenEndpointAuthority(
159
+ authCodeResponse.cloud_instance_host_name,
160
+ authority,
161
+ networkModule
162
+ );
163
+ }
164
+
165
+ // Nonce validation not needed when redirect not involved (e.g. hybrid spa, renewing token via rt)
166
+ if (validateNonce) {
167
+ authCodeResponse.nonce = cachedNonce || undefined;
168
+ }
169
+
170
+ authCodeResponse.state = requestState;
171
+
172
+ // Add CCS parameters if available
173
+ if (authCodeResponse.client_info) {
174
+ this.authCodeRequest.clientInfo = authCodeResponse.client_info;
175
+ } else {
176
+ const cachedCcsCred = this.checkCcsCredentials();
177
+ if (cachedCcsCred) {
178
+ this.authCodeRequest.ccsCredential = cachedCcsCred;
179
+ }
180
+ }
181
+
182
+ // Acquire token with retrieved code.
183
+ const tokenResponse = (await invokeAsync(
184
+ this.authModule.acquireToken.bind(this.authModule),
185
+ PerformanceEvents.AuthClientAcquireToken,
186
+ this.logger,
187
+ this.performanceClient,
188
+ this.authCodeRequest.correlationId
189
+ )(this.authCodeRequest, authCodeResponse)) as AuthenticationResult;
190
+ this.browserStorage.cleanRequestByState(state);
191
+ return tokenResponse;
192
+ }
193
+
194
+ /**
195
+ * Updates authority based on cloudInstanceHostname
196
+ * @param cloudInstanceHostname
197
+ * @param authority
198
+ * @param networkModule
199
+ */
200
+ protected async updateTokenEndpointAuthority(
201
+ cloudInstanceHostname: string,
202
+ authority: Authority,
203
+ networkModule: INetworkModule
204
+ ): Promise<void> {
205
+ this.performanceClient.addQueueMeasurement(
206
+ PerformanceEvents.UpdateTokenEndpointAuthority,
207
+ this.authCodeRequest.correlationId
208
+ );
209
+ const cloudInstanceAuthorityUri = `https://${cloudInstanceHostname}/${authority.tenant}/`;
210
+ const cloudInstanceAuthority =
211
+ await AuthorityFactory.createDiscoveredInstance(
212
+ cloudInstanceAuthorityUri,
213
+ networkModule,
214
+ this.browserStorage,
215
+ authority.options,
216
+ this.logger,
217
+ this.performanceClient,
218
+ this.authCodeRequest.correlationId
219
+ );
220
+ this.authModule.updateAuthority(cloudInstanceAuthority);
221
+ }
222
+
223
+ /**
224
+ * Looks up ccs creds in the cache
225
+ */
226
+ protected checkCcsCredentials(): CcsCredential | null {
227
+ // Look up ccs credential in temp cache
228
+ const cachedCcsCred = this.browserStorage.getTemporaryCache(
229
+ TemporaryCacheKeys.CCS_CREDENTIAL,
230
+ true
231
+ );
232
+ if (cachedCcsCred) {
233
+ try {
234
+ return JSON.parse(cachedCcsCred) as CcsCredential;
235
+ } catch (e) {
236
+ this.authModule.logger.error(
237
+ "Cache credential could not be parsed"
238
+ );
239
+ this.authModule.logger.errorPii(
240
+ `Cache credential could not be parsed: ${cachedCcsCred}`
241
+ );
242
+ }
243
+ }
244
+ return null;
245
+ }
246
+ }
@@ -0,0 +1,225 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ AuthorizationCodeClient,
8
+ CommonAuthorizationCodeRequest,
9
+ ICrypto,
10
+ Authority,
11
+ INetworkModule,
12
+ ClientAuthError,
13
+ Logger,
14
+ ServerError,
15
+ IPerformanceClient,
16
+ } from "@azure/msal-common";
17
+ import {
18
+ createBrowserAuthError,
19
+ BrowserAuthErrorCodes,
20
+ } from "../error/BrowserAuthError";
21
+ import { ApiId, TemporaryCacheKeys } from "../utils/BrowserConstants";
22
+ import { BrowserCacheManager } from "../cache/BrowserCacheManager";
23
+ import { InteractionHandler, InteractionParams } from "./InteractionHandler";
24
+ import { INavigationClient } from "../navigation/INavigationClient";
25
+ import { NavigationOptions } from "../navigation/NavigationOptions";
26
+ import { AuthenticationResult } from "../response/AuthenticationResult";
27
+
28
+ export type RedirectParams = InteractionParams & {
29
+ navigationClient: INavigationClient;
30
+ redirectTimeout: number;
31
+ redirectStartPage: string;
32
+ onRedirectNavigate?: (url: string) => void | boolean;
33
+ };
34
+
35
+ export class RedirectHandler extends InteractionHandler {
36
+ private browserCrypto: ICrypto;
37
+
38
+ constructor(
39
+ authCodeModule: AuthorizationCodeClient,
40
+ storageImpl: BrowserCacheManager,
41
+ authCodeRequest: CommonAuthorizationCodeRequest,
42
+ logger: Logger,
43
+ browserCrypto: ICrypto,
44
+ performanceClient: IPerformanceClient
45
+ ) {
46
+ super(
47
+ authCodeModule,
48
+ storageImpl,
49
+ authCodeRequest,
50
+ logger,
51
+ performanceClient
52
+ );
53
+ this.browserCrypto = browserCrypto;
54
+ }
55
+
56
+ /**
57
+ * Redirects window to given URL.
58
+ * @param urlNavigate
59
+ */
60
+ async initiateAuthRequest(
61
+ requestUrl: string,
62
+ params: RedirectParams
63
+ ): Promise<void> {
64
+ this.logger.verbose("RedirectHandler.initiateAuthRequest called");
65
+ // Navigate if valid URL
66
+ if (requestUrl) {
67
+ // Cache start page, returns to this page after redirectUri if navigateToLoginRequestUrl is true
68
+ if (params.redirectStartPage) {
69
+ this.logger.verbose(
70
+ "RedirectHandler.initiateAuthRequest: redirectStartPage set, caching start page"
71
+ );
72
+ this.browserStorage.setTemporaryCache(
73
+ TemporaryCacheKeys.ORIGIN_URI,
74
+ params.redirectStartPage,
75
+ true
76
+ );
77
+ }
78
+
79
+ // Set interaction status in the library.
80
+ this.browserStorage.setTemporaryCache(
81
+ TemporaryCacheKeys.CORRELATION_ID,
82
+ this.authCodeRequest.correlationId,
83
+ true
84
+ );
85
+ this.browserStorage.cacheCodeRequest(this.authCodeRequest);
86
+ this.logger.infoPii(
87
+ `RedirectHandler.initiateAuthRequest: Navigate to: ${requestUrl}`
88
+ );
89
+ const navigationOptions: NavigationOptions = {
90
+ apiId: ApiId.acquireTokenRedirect,
91
+ timeout: params.redirectTimeout,
92
+ noHistory: false,
93
+ };
94
+
95
+ // If onRedirectNavigate is implemented, invoke it and provide requestUrl
96
+ if (typeof params.onRedirectNavigate === "function") {
97
+ this.logger.verbose(
98
+ "RedirectHandler.initiateAuthRequest: Invoking onRedirectNavigate callback"
99
+ );
100
+ const navigate = params.onRedirectNavigate(requestUrl);
101
+
102
+ // Returning false from onRedirectNavigate will stop navigation
103
+ if (navigate !== false) {
104
+ this.logger.verbose(
105
+ "RedirectHandler.initiateAuthRequest: onRedirectNavigate did not return false, navigating"
106
+ );
107
+ await params.navigationClient.navigateExternal(
108
+ requestUrl,
109
+ navigationOptions
110
+ );
111
+ return;
112
+ } else {
113
+ this.logger.verbose(
114
+ "RedirectHandler.initiateAuthRequest: onRedirectNavigate returned false, stopping navigation"
115
+ );
116
+ return;
117
+ }
118
+ } else {
119
+ // Navigate window to request URL
120
+ this.logger.verbose(
121
+ "RedirectHandler.initiateAuthRequest: Navigating window to navigate url"
122
+ );
123
+ await params.navigationClient.navigateExternal(
124
+ requestUrl,
125
+ navigationOptions
126
+ );
127
+ return;
128
+ }
129
+ } else {
130
+ // Throw error if request URL is empty.
131
+ this.logger.info(
132
+ "RedirectHandler.initiateAuthRequest: Navigate url is empty"
133
+ );
134
+ throw createBrowserAuthError(
135
+ BrowserAuthErrorCodes.emptyNavigateUri
136
+ );
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Handle authorization code response in the window.
142
+ * @param hash
143
+ */
144
+ async handleCodeResponseFromHash(
145
+ locationHash: string,
146
+ state: string,
147
+ authority: Authority,
148
+ networkModule: INetworkModule
149
+ ): Promise<AuthenticationResult> {
150
+ this.logger.verbose("RedirectHandler.handleCodeResponse called");
151
+
152
+ // Check that location hash isn't empty.
153
+ if (!locationHash) {
154
+ throw createBrowserAuthError(BrowserAuthErrorCodes.hashEmptyError);
155
+ }
156
+
157
+ // Interaction is completed - remove interaction status.
158
+ this.browserStorage.setInteractionInProgress(false);
159
+
160
+ // Handle code response.
161
+ const stateKey = this.browserStorage.generateStateKey(state);
162
+ const requestState = this.browserStorage.getTemporaryCache(stateKey);
163
+ if (!requestState) {
164
+ throw ClientAuthError.createStateNotFoundError("Cached State");
165
+ }
166
+
167
+ let authCodeResponse;
168
+ try {
169
+ authCodeResponse = this.authModule.handleFragmentResponse(
170
+ locationHash,
171
+ requestState
172
+ );
173
+ } catch (e) {
174
+ if (
175
+ e instanceof ServerError &&
176
+ e.subError === BrowserAuthErrorCodes.userCancelled
177
+ ) {
178
+ // Translate server error caused by user closing native prompt to corresponding first class MSAL error
179
+ throw createBrowserAuthError(
180
+ BrowserAuthErrorCodes.userCancelled
181
+ );
182
+ } else {
183
+ throw e;
184
+ }
185
+ }
186
+
187
+ // Get cached items
188
+ const nonceKey = this.browserStorage.generateNonceKey(requestState);
189
+ const cachedNonce = this.browserStorage.getTemporaryCache(nonceKey);
190
+
191
+ // Assign code to request
192
+ this.authCodeRequest.code = authCodeResponse.code;
193
+
194
+ // Check for new cloud instance
195
+ if (authCodeResponse.cloud_instance_host_name) {
196
+ await this.updateTokenEndpointAuthority(
197
+ authCodeResponse.cloud_instance_host_name,
198
+ authority,
199
+ networkModule
200
+ );
201
+ }
202
+
203
+ authCodeResponse.nonce = cachedNonce || undefined;
204
+ authCodeResponse.state = requestState;
205
+
206
+ // Add CCS parameters if available
207
+ if (authCodeResponse.client_info) {
208
+ this.authCodeRequest.clientInfo = authCodeResponse.client_info;
209
+ } else {
210
+ const cachedCcsCred = this.checkCcsCredentials();
211
+ if (cachedCcsCred) {
212
+ this.authCodeRequest.ccsCredential = cachedCcsCred;
213
+ }
214
+ }
215
+
216
+ // Acquire token with retrieved code.
217
+ const tokenResponse = (await this.authModule.acquireToken(
218
+ this.authCodeRequest,
219
+ authCodeResponse
220
+ )) as AuthenticationResult;
221
+
222
+ this.browserStorage.cleanRequestByState(state);
223
+ return tokenResponse;
224
+ }
225
+ }