@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,266 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ UrlString,
8
+ CommonAuthorizationCodeRequest,
9
+ AuthorizationCodeClient,
10
+ Constants,
11
+ Logger,
12
+ IPerformanceClient,
13
+ PerformanceEvents,
14
+ } from "@azure/msal-common";
15
+ import { InteractionHandler } from "./InteractionHandler";
16
+ import {
17
+ createBrowserAuthError,
18
+ BrowserAuthErrorCodes,
19
+ } from "../error/BrowserAuthError";
20
+ import { BrowserCacheManager } from "../cache/BrowserCacheManager";
21
+ import {
22
+ BrowserSystemOptions,
23
+ DEFAULT_IFRAME_TIMEOUT_MS,
24
+ } from "../config/Configuration";
25
+
26
+ export class SilentHandler extends InteractionHandler {
27
+ private navigateFrameWait: number;
28
+ private pollIntervalMilliseconds: number;
29
+
30
+ constructor(
31
+ authCodeModule: AuthorizationCodeClient,
32
+ storageImpl: BrowserCacheManager,
33
+ authCodeRequest: CommonAuthorizationCodeRequest,
34
+ logger: Logger,
35
+ systemOptions: Required<
36
+ Pick<
37
+ BrowserSystemOptions,
38
+ "navigateFrameWait" | "pollIntervalMilliseconds"
39
+ >
40
+ >,
41
+ performanceClient: IPerformanceClient
42
+ ) {
43
+ super(
44
+ authCodeModule,
45
+ storageImpl,
46
+ authCodeRequest,
47
+ logger,
48
+ performanceClient
49
+ );
50
+ this.navigateFrameWait = systemOptions.navigateFrameWait;
51
+ this.pollIntervalMilliseconds = systemOptions.pollIntervalMilliseconds;
52
+ }
53
+
54
+ /**
55
+ * Creates a hidden iframe to given URL using user-requested scopes as an id.
56
+ * @param urlNavigate
57
+ * @param userRequestScopes
58
+ */
59
+ async initiateAuthRequest(requestUrl: string): Promise<HTMLIFrameElement> {
60
+ this.performanceClient.addQueueMeasurement(
61
+ PerformanceEvents.SilentHandlerInitiateAuthRequest,
62
+ this.authCodeRequest.correlationId
63
+ );
64
+
65
+ if (!requestUrl) {
66
+ // Throw error if request URL is empty.
67
+ this.logger.info("Navigate url is empty");
68
+ throw createBrowserAuthError(
69
+ BrowserAuthErrorCodes.emptyNavigateUri
70
+ );
71
+ }
72
+
73
+ if (this.navigateFrameWait) {
74
+ this.performanceClient.setPreQueueTime(
75
+ PerformanceEvents.SilentHandlerLoadFrame,
76
+ this.authCodeRequest.correlationId
77
+ );
78
+ return await this.loadFrame(requestUrl);
79
+ }
80
+ return this.loadFrameSync(requestUrl);
81
+ }
82
+
83
+ /**
84
+ * Monitors an iframe content window until it loads a url with a known hash, or hits a specified timeout.
85
+ * @param iframe
86
+ * @param timeout
87
+ */
88
+ monitorIframeForHash(
89
+ iframe: HTMLIFrameElement,
90
+ timeout: number
91
+ ): Promise<string> {
92
+ this.performanceClient.addQueueMeasurement(
93
+ PerformanceEvents.SilentHandlerMonitorIframeForHash,
94
+ this.authCodeRequest.correlationId
95
+ );
96
+
97
+ return new Promise((resolve, reject) => {
98
+ if (timeout < DEFAULT_IFRAME_TIMEOUT_MS) {
99
+ this.logger.warning(
100
+ `system.loadFrameTimeout or system.iframeHashTimeout set to lower (${timeout}ms) than the default (${DEFAULT_IFRAME_TIMEOUT_MS}ms). This may result in timeouts.`
101
+ );
102
+ }
103
+
104
+ /*
105
+ * Polling for iframes can be purely timing based,
106
+ * since we don't need to account for interaction.
107
+ */
108
+ const nowMark = window.performance.now();
109
+ const timeoutMark = nowMark + timeout;
110
+
111
+ const intervalId = setInterval(() => {
112
+ if (window.performance.now() > timeoutMark) {
113
+ this.removeHiddenIframe(iframe);
114
+ clearInterval(intervalId);
115
+ reject(
116
+ createBrowserAuthError(
117
+ BrowserAuthErrorCodes.monitorWindowTimeout
118
+ )
119
+ );
120
+ return;
121
+ }
122
+
123
+ let href: string = Constants.EMPTY_STRING;
124
+ const contentWindow = iframe.contentWindow;
125
+ try {
126
+ /*
127
+ * Will throw if cross origin,
128
+ * which should be caught and ignored
129
+ * since we need the interval to keep running while on STS UI.
130
+ */
131
+ href = contentWindow
132
+ ? contentWindow.location.href
133
+ : Constants.EMPTY_STRING;
134
+ } catch (e) {}
135
+
136
+ if (!href || href === "about:blank") {
137
+ return;
138
+ }
139
+
140
+ const contentHash = contentWindow
141
+ ? contentWindow.location.hash
142
+ : Constants.EMPTY_STRING;
143
+ if (contentHash) {
144
+ if (UrlString.hashContainsKnownProperties(contentHash)) {
145
+ // Success case
146
+ this.removeHiddenIframe(iframe);
147
+ clearInterval(intervalId);
148
+ resolve(contentHash);
149
+ return;
150
+ } else {
151
+ // Hash is present but incorrect
152
+ this.logger.error(
153
+ "SilentHandler:monitorIFrameForHash - a hash is present in the iframe but it does not contain known properties. It's likely that the hash has been replaced by code running on the redirectUri page."
154
+ );
155
+ this.logger.errorPii(
156
+ `SilentHandler:monitorIFrameForHash - the url detected in the iframe is: ${href}`
157
+ );
158
+ this.removeHiddenIframe(iframe);
159
+ clearInterval(intervalId);
160
+ reject(
161
+ createBrowserAuthError(
162
+ BrowserAuthErrorCodes.hashDoesNotContainKnownProperties
163
+ )
164
+ );
165
+ return;
166
+ }
167
+ } else {
168
+ // No hash is present
169
+ this.logger.error(
170
+ "SilentHandler:monitorIFrameForHash - the request has returned to the redirectUri but a hash is not present in the iframe. It's likely that the hash has been removed or the page has been redirected by code running on the redirectUri page."
171
+ );
172
+ this.logger.errorPii(
173
+ `SilentHandler:monitorIFrameForHash - the url detected in the iframe is: ${href}`
174
+ );
175
+ this.removeHiddenIframe(iframe);
176
+ clearInterval(intervalId);
177
+ reject(
178
+ createBrowserAuthError(
179
+ BrowserAuthErrorCodes.hashEmptyError
180
+ )
181
+ );
182
+ return;
183
+ }
184
+ }, this.pollIntervalMilliseconds);
185
+ });
186
+ }
187
+
188
+ /**
189
+ * @hidden
190
+ * Loads iframe with authorization endpoint URL
191
+ * @ignore
192
+ */
193
+ private loadFrame(urlNavigate: string): Promise<HTMLIFrameElement> {
194
+ this.performanceClient.addQueueMeasurement(
195
+ PerformanceEvents.SilentHandlerLoadFrame,
196
+ this.authCodeRequest.correlationId
197
+ );
198
+
199
+ /*
200
+ * This trick overcomes iframe navigation in IE
201
+ * IE does not load the page consistently in iframe
202
+ */
203
+
204
+ return new Promise((resolve, reject) => {
205
+ const frameHandle = this.createHiddenIframe();
206
+
207
+ setTimeout(() => {
208
+ if (!frameHandle) {
209
+ reject("Unable to load iframe");
210
+ return;
211
+ }
212
+
213
+ frameHandle.src = urlNavigate;
214
+
215
+ resolve(frameHandle);
216
+ }, this.navigateFrameWait);
217
+ });
218
+ }
219
+
220
+ /**
221
+ * @hidden
222
+ * Loads the iframe synchronously when the navigateTimeFrame is set to `0`
223
+ * @param urlNavigate
224
+ * @param frameName
225
+ * @param logger
226
+ */
227
+ private loadFrameSync(urlNavigate: string): HTMLIFrameElement {
228
+ const frameHandle = this.createHiddenIframe();
229
+
230
+ frameHandle.src = urlNavigate;
231
+
232
+ return frameHandle;
233
+ }
234
+
235
+ /**
236
+ * @hidden
237
+ * Creates a new hidden iframe or gets an existing one for silent token renewal.
238
+ * @ignore
239
+ */
240
+ private createHiddenIframe(): HTMLIFrameElement {
241
+ const authFrame = document.createElement("iframe");
242
+
243
+ authFrame.style.visibility = "hidden";
244
+ authFrame.style.position = "absolute";
245
+ authFrame.style.width = authFrame.style.height = "0";
246
+ authFrame.style.border = "0";
247
+ authFrame.setAttribute(
248
+ "sandbox",
249
+ "allow-scripts allow-same-origin allow-forms"
250
+ );
251
+ document.getElementsByTagName("body")[0].appendChild(authFrame);
252
+
253
+ return authFrame;
254
+ }
255
+
256
+ /**
257
+ * @hidden
258
+ * Removes a hidden iframe from the page.
259
+ * @ignore
260
+ */
261
+ private removeHiddenIframe(iframe: HTMLIFrameElement): void {
262
+ if (document.body === iframe.parentNode) {
263
+ document.body.removeChild(iframe);
264
+ }
265
+ }
266
+ }
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { NavigationOptions } from "./NavigationOptions";
7
+
8
+ export interface INavigationClient {
9
+ /**
10
+ * Navigates to other pages within the same web application
11
+ * Return false if this doesn't cause the page to reload i.e. Client-side navigation
12
+ * @param url
13
+ * @param options
14
+ */
15
+ navigateInternal(url: string, options: NavigationOptions): Promise<boolean>;
16
+
17
+ /**
18
+ * Navigates to other pages outside the web application i.e. the Identity Provider
19
+ * @param url
20
+ * @param options
21
+ */
22
+ navigateExternal(url: string, options: NavigationOptions): Promise<boolean>;
23
+ }
@@ -0,0 +1,55 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { INavigationClient } from "./INavigationClient";
7
+ import { NavigationOptions } from "./NavigationOptions";
8
+
9
+ export class NavigationClient implements INavigationClient {
10
+ /**
11
+ * Navigates to other pages within the same web application
12
+ * @param url
13
+ * @param options
14
+ */
15
+ navigateInternal(
16
+ url: string,
17
+ options: NavigationOptions
18
+ ): Promise<boolean> {
19
+ return NavigationClient.defaultNavigateWindow(url, options);
20
+ }
21
+
22
+ /**
23
+ * Navigates to other pages outside the web application i.e. the Identity Provider
24
+ * @param url
25
+ * @param options
26
+ */
27
+ navigateExternal(
28
+ url: string,
29
+ options: NavigationOptions
30
+ ): Promise<boolean> {
31
+ return NavigationClient.defaultNavigateWindow(url, options);
32
+ }
33
+
34
+ /**
35
+ * Default navigation implementation invoked by the internal and external functions
36
+ * @param url
37
+ * @param options
38
+ */
39
+ private static defaultNavigateWindow(
40
+ url: string,
41
+ options: NavigationOptions
42
+ ): Promise<boolean> {
43
+ if (options.noHistory) {
44
+ window.location.replace(url);
45
+ } else {
46
+ window.location.assign(url);
47
+ }
48
+
49
+ return new Promise((resolve) => {
50
+ setTimeout(() => {
51
+ resolve(true);
52
+ }, options.timeout);
53
+ });
54
+ }
55
+ }
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { ApiId } from "../utils/BrowserConstants";
7
+
8
+ /**
9
+ * Additional information passed to the navigateInternal and navigateExternal functions
10
+ */
11
+ export type NavigationOptions = {
12
+ /** The Id of the API that initiated navigation */
13
+ apiId: ApiId;
14
+ /** Suggested timeout (ms) based on the configuration provided to PublicClientApplication */
15
+ timeout: number;
16
+ /** When set to true the url should not be added to the browser history */
17
+ noHistory: boolean;
18
+ };
@@ -0,0 +1,130 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ Constants,
8
+ INetworkModule,
9
+ NetworkRequestOptions,
10
+ NetworkResponse,
11
+ } from "@azure/msal-common";
12
+ import {
13
+ createBrowserAuthError,
14
+ BrowserAuthErrorCodes,
15
+ } from "../error/BrowserAuthError";
16
+ import { HTTP_REQUEST_TYPE } from "../utils/BrowserConstants";
17
+
18
+ /**
19
+ * This class implements the Fetch API for GET and POST requests. See more here: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
20
+ */
21
+ export class FetchClient implements INetworkModule {
22
+ /**
23
+ * Fetch Client for REST endpoints - Get request
24
+ * @param url
25
+ * @param headers
26
+ * @param body
27
+ */
28
+ async sendGetRequestAsync<T>(
29
+ url: string,
30
+ options?: NetworkRequestOptions
31
+ ): Promise<NetworkResponse<T>> {
32
+ let response;
33
+ try {
34
+ response = await fetch(url, {
35
+ method: HTTP_REQUEST_TYPE.GET,
36
+ headers: this.getFetchHeaders(options),
37
+ });
38
+ } catch (e) {
39
+ if (window.navigator.onLine) {
40
+ throw createBrowserAuthError(
41
+ BrowserAuthErrorCodes.getRequestFailed
42
+ );
43
+ } else {
44
+ throw createBrowserAuthError(
45
+ BrowserAuthErrorCodes.noNetworkConnectivity
46
+ );
47
+ }
48
+ }
49
+
50
+ try {
51
+ return {
52
+ headers: this.getHeaderDict(response.headers),
53
+ body: (await response.json()) as T,
54
+ status: response.status,
55
+ };
56
+ } catch (e) {
57
+ throw createBrowserAuthError(
58
+ BrowserAuthErrorCodes.failedToParseResponse
59
+ );
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Fetch Client for REST endpoints - Post request
65
+ * @param url
66
+ * @param headers
67
+ * @param body
68
+ */
69
+ async sendPostRequestAsync<T>(
70
+ url: string,
71
+ options?: NetworkRequestOptions
72
+ ): Promise<NetworkResponse<T>> {
73
+ const reqBody = (options && options.body) || Constants.EMPTY_STRING;
74
+
75
+ let response;
76
+ try {
77
+ response = await fetch(url, {
78
+ method: HTTP_REQUEST_TYPE.POST,
79
+ headers: this.getFetchHeaders(options),
80
+ body: reqBody,
81
+ });
82
+ } catch (e) {
83
+ if (window.navigator.onLine) {
84
+ throw createBrowserAuthError(
85
+ BrowserAuthErrorCodes.postRequestFailed
86
+ );
87
+ } else {
88
+ throw createBrowserAuthError(
89
+ BrowserAuthErrorCodes.noNetworkConnectivity
90
+ );
91
+ }
92
+ }
93
+
94
+ try {
95
+ return {
96
+ headers: this.getHeaderDict(response.headers),
97
+ body: (await response.json()) as T,
98
+ status: response.status,
99
+ };
100
+ } catch (e) {
101
+ throw createBrowserAuthError(
102
+ BrowserAuthErrorCodes.failedToParseResponse
103
+ );
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Get Fetch API Headers object from string map
109
+ * @param inputHeaders
110
+ */
111
+ private getFetchHeaders(options?: NetworkRequestOptions): Headers {
112
+ const headers = new Headers();
113
+ if (!(options && options.headers)) {
114
+ return headers;
115
+ }
116
+ const optionsHeaders = options.headers;
117
+ Object.keys(optionsHeaders).forEach((key) => {
118
+ headers.append(key, optionsHeaders[key]);
119
+ });
120
+ return headers;
121
+ }
122
+
123
+ private getHeaderDict(headers: Headers): Record<string, string> {
124
+ const headerDict: Record<string, string> = {};
125
+ headers.forEach((value: string, key: string) => {
126
+ headerDict[key] = value;
127
+ });
128
+ return headerDict;
129
+ }
130
+ }
@@ -0,0 +1,82 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { Logger } from "@azure/msal-common";
7
+ import {
8
+ BrowserConfiguration,
9
+ buildConfiguration,
10
+ Configuration,
11
+ } from "../config/Configuration";
12
+ import { version, name } from "../packageMetadata";
13
+
14
+ /**
15
+ * Base class for operating context
16
+ * Operating contexts are contexts in which MSAL.js is being run
17
+ * More than one operating context may be available at a time
18
+ * It's important from a logging and telemetry point of view for us to be able to identify the operating context.
19
+ * For example: Some operating contexts will pre-cache tokens impacting performance telemetry
20
+ */
21
+ export abstract class BaseOperatingContext {
22
+ protected logger: Logger;
23
+ protected config: BrowserConfiguration;
24
+ protected available: boolean;
25
+ protected browserEnvironment: boolean;
26
+
27
+ constructor(config: Configuration) {
28
+ /*
29
+ * If loaded in an environment where window is not available,
30
+ * set internal flag to false so that further requests fail.
31
+ * This is to support server-side rendering environments.
32
+ */
33
+ this.browserEnvironment = typeof window !== "undefined";
34
+
35
+ this.config = buildConfiguration(config, this.browserEnvironment);
36
+ this.logger = new Logger(
37
+ this.config.system.loggerOptions,
38
+ name,
39
+ version
40
+ );
41
+ this.available = false;
42
+ }
43
+
44
+ /**
45
+ * returns the name of the module containing the API controller associated with this operating context
46
+ */
47
+ abstract getModuleName(): string;
48
+
49
+ /**
50
+ * returns the string identifier of this operating context
51
+ */
52
+ abstract getId(): string;
53
+
54
+ /**
55
+ * returns a boolean indicating whether this operating context is present
56
+ */
57
+ abstract initialize(): Promise<boolean>;
58
+
59
+ /**
60
+ * Return the MSAL config
61
+ * @returns BrowserConfiguration
62
+ */
63
+ getConfig(): BrowserConfiguration {
64
+ return this.config;
65
+ }
66
+
67
+ /**
68
+ * Returns the MSAL Logger
69
+ * @returns Logger
70
+ */
71
+ getLogger(): Logger {
72
+ return this.logger;
73
+ }
74
+
75
+ isAvailable(): boolean {
76
+ return this.available;
77
+ }
78
+
79
+ isBrowserEnvironment(): boolean {
80
+ return this.browserEnvironment;
81
+ }
82
+ }
@@ -0,0 +1,49 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { BaseOperatingContext } from "./BaseOperatingContext";
7
+
8
+ export class StandardOperatingContext extends BaseOperatingContext {
9
+ /*
10
+ * TODO: Once we have determine the bundling code return here to specify the name of the bundle
11
+ * containing the implementation for this operating context
12
+ */
13
+ static readonly MODULE_NAME: string = "";
14
+
15
+ /**
16
+ * Unique identifier for the operating context
17
+ */
18
+ static readonly ID: string = "StandardOperatingContext";
19
+
20
+ /**
21
+ * Return the module name. Intended for use with import() to enable dynamic import
22
+ * of the implementation associated with this operating context
23
+ * @returns
24
+ */
25
+ getModuleName(): string {
26
+ return StandardOperatingContext.MODULE_NAME;
27
+ }
28
+ /**
29
+ * Returns the unique identifier for this operating context
30
+ * @returns string
31
+ */
32
+ getId(): string {
33
+ return StandardOperatingContext.ID;
34
+ }
35
+
36
+ /**
37
+ * Checks whether the operating context is available.
38
+ * Confirms that the code is running a browser rather. This is required.
39
+ * @returns Promise<boolean> indicating whether this operating context is currently available.
40
+ */
41
+ async initialize(): Promise<boolean> {
42
+ this.available = typeof window !== "undefined";
43
+ return this.available;
44
+ /*
45
+ * NOTE: The standard context is available as long as there is a window. If/when we split out WAM from Browser
46
+ * We can move the current contents of the initialize method to here and verify that the WAM extension is available
47
+ */
48
+ }
49
+ }
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { BaseOperatingContext } from "./BaseOperatingContext";
7
+
8
+ export class TeamsAppOperatingContext extends BaseOperatingContext {
9
+ /*
10
+ * TODO: Once we have determine the bundling code return here to specify the name of the bundle
11
+ * containing the implementation for this operating context
12
+ */
13
+ static readonly MODULE_NAME: string = "";
14
+
15
+ /**
16
+ * Unique identifier for the operating context
17
+ */
18
+ static readonly ID: string = "TeamsAppOperatingContext";
19
+
20
+ /**
21
+ * Return the module name. Intended for use with import() to enable dynamic import
22
+ * of the implementation associated with this operating context
23
+ * @returns
24
+ */
25
+ getModuleName(): string {
26
+ return TeamsAppOperatingContext.MODULE_NAME;
27
+ }
28
+ /**
29
+ * Returns the unique identifier for this operating context
30
+ * @returns string
31
+ */
32
+ getId(): string {
33
+ return TeamsAppOperatingContext.ID;
34
+ }
35
+
36
+ /**
37
+ * Checks whether the operating context is available.
38
+ * Confirms that the code is running a browser rather. This is required.
39
+ * @returns Promise<boolean> indicating whether this operating context is currently available.
40
+ */
41
+ async initialize(): Promise<boolean> {
42
+ /*
43
+ * TODO: Add implementation to check for presence of inject MetaOSHub JavaScript interface
44
+ * TODO: Make pre-flight token request to ensure that App is eligible to use Nested App Auth
45
+ */
46
+ return false;
47
+ }
48
+ }
@@ -0,0 +1,3 @@
1
+ /* eslint-disable header/header */
2
+ export const name = "@azure/msal-browser";
3
+ export const version = "3.1.0";
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { CommonAuthorizationCodeRequest } from "@azure/msal-common";
7
+
8
+ export type AuthorizationCodeRequest = Partial<
9
+ Omit<
10
+ CommonAuthorizationCodeRequest,
11
+ "code" | "enableSpaAuthorizationCode" | "requestedClaimsHash"
12
+ >
13
+ > & {
14
+ code?: string;
15
+ nativeAccountId?: string;
16
+ cloudGraphHostName?: string;
17
+ msGraphHost?: string;
18
+ cloudInstanceHostName?: string;
19
+ };