@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,163 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ ICrypto,
8
+ Logger,
9
+ CommonAuthorizationCodeRequest,
10
+ AuthError,
11
+ Constants,
12
+ IPerformanceClient,
13
+ PerformanceEvents,
14
+ } from "@azure/msal-common";
15
+ import { StandardInteractionClient } from "./StandardInteractionClient";
16
+ import { AuthorizationUrlRequest } from "../request/AuthorizationUrlRequest";
17
+ import { BrowserConfiguration } from "../config/Configuration";
18
+ import { BrowserCacheManager } from "../cache/BrowserCacheManager";
19
+ import { EventHandler } from "../event/EventHandler";
20
+ import { INavigationClient } from "../navigation/INavigationClient";
21
+ import {
22
+ createBrowserAuthError,
23
+ BrowserAuthErrorCodes,
24
+ } from "../error/BrowserAuthError";
25
+ import { InteractionType, ApiId } from "../utils/BrowserConstants";
26
+ import { SilentHandler } from "../interaction_handler/SilentHandler";
27
+ import { AuthorizationCodeRequest } from "../request/AuthorizationCodeRequest";
28
+ import { HybridSpaAuthorizationCodeClient } from "./HybridSpaAuthorizationCodeClient";
29
+ import { NativeMessageHandler } from "../broker/nativeBroker/NativeMessageHandler";
30
+ import { AuthenticationResult } from "../response/AuthenticationResult";
31
+
32
+ export class SilentAuthCodeClient extends StandardInteractionClient {
33
+ private apiId: ApiId;
34
+
35
+ constructor(
36
+ config: BrowserConfiguration,
37
+ storageImpl: BrowserCacheManager,
38
+ browserCrypto: ICrypto,
39
+ logger: Logger,
40
+ eventHandler: EventHandler,
41
+ navigationClient: INavigationClient,
42
+ apiId: ApiId,
43
+ performanceClient: IPerformanceClient,
44
+ nativeMessageHandler?: NativeMessageHandler,
45
+ correlationId?: string
46
+ ) {
47
+ super(
48
+ config,
49
+ storageImpl,
50
+ browserCrypto,
51
+ logger,
52
+ eventHandler,
53
+ navigationClient,
54
+ performanceClient,
55
+ nativeMessageHandler,
56
+ correlationId
57
+ );
58
+ this.apiId = apiId;
59
+ }
60
+
61
+ /**
62
+ * Acquires a token silently by redeeming an authorization code against the /token endpoint
63
+ * @param request
64
+ */
65
+ async acquireToken(
66
+ request: AuthorizationCodeRequest
67
+ ): Promise<AuthenticationResult> {
68
+ this.logger.trace("SilentAuthCodeClient.acquireToken called");
69
+
70
+ // Auth code payload is required
71
+ if (!request.code) {
72
+ throw createBrowserAuthError(
73
+ BrowserAuthErrorCodes.authCodeRequired
74
+ );
75
+ }
76
+
77
+ // Create silent request
78
+ this.performanceClient.setPreQueueTime(
79
+ PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest,
80
+ request.correlationId
81
+ );
82
+ const silentRequest: AuthorizationUrlRequest =
83
+ await this.initializeAuthorizationRequest(
84
+ request,
85
+ InteractionType.Silent
86
+ );
87
+ this.browserStorage.updateCacheEntries(
88
+ silentRequest.state,
89
+ silentRequest.nonce,
90
+ silentRequest.authority,
91
+ silentRequest.loginHint || Constants.EMPTY_STRING,
92
+ silentRequest.account || null
93
+ );
94
+
95
+ const serverTelemetryManager = this.initializeServerTelemetryManager(
96
+ this.apiId
97
+ );
98
+
99
+ try {
100
+ // Create auth code request (PKCE not needed)
101
+ const authCodeRequest: CommonAuthorizationCodeRequest = {
102
+ ...silentRequest,
103
+ code: request.code,
104
+ };
105
+
106
+ // Initialize the client
107
+ this.performanceClient.setPreQueueTime(
108
+ PerformanceEvents.StandardInteractionClientGetClientConfiguration,
109
+ request.correlationId
110
+ );
111
+ const clientConfig = await this.getClientConfiguration(
112
+ serverTelemetryManager,
113
+ silentRequest.authority
114
+ );
115
+ const authClient: HybridSpaAuthorizationCodeClient =
116
+ new HybridSpaAuthorizationCodeClient(clientConfig);
117
+ this.logger.verbose("Auth code client created");
118
+
119
+ // Create silent handler
120
+ const silentHandler = new SilentHandler(
121
+ authClient,
122
+ this.browserStorage,
123
+ authCodeRequest,
124
+ this.logger,
125
+ this.config.system,
126
+ this.performanceClient
127
+ );
128
+
129
+ // Handle auth code parameters from request
130
+ return silentHandler.handleCodeResponseFromServer(
131
+ {
132
+ code: request.code,
133
+ msgraph_host: request.msGraphHost,
134
+ cloud_graph_host_name: request.cloudGraphHostName,
135
+ cloud_instance_host_name: request.cloudInstanceHostName,
136
+ },
137
+ silentRequest.state,
138
+ authClient.authority,
139
+ this.networkClient,
140
+ false
141
+ );
142
+ } catch (e) {
143
+ if (e instanceof AuthError) {
144
+ (e as AuthError).setCorrelationId(this.correlationId);
145
+ serverTelemetryManager.cacheFailedRequest(e);
146
+ }
147
+ this.browserStorage.cleanRequestByState(silentRequest.state);
148
+ throw e;
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Currently Unsupported
154
+ */
155
+ logout(): Promise<void> {
156
+ // Synchronous so we must reject
157
+ return Promise.reject(
158
+ createBrowserAuthError(
159
+ BrowserAuthErrorCodes.silentLogoutUnsupported
160
+ )
161
+ );
162
+ }
163
+ }
@@ -0,0 +1,133 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { StandardInteractionClient } from "./StandardInteractionClient";
7
+ import {
8
+ CommonSilentFlowRequest,
9
+ SilentFlowClient,
10
+ ServerTelemetryManager,
11
+ AccountInfo,
12
+ AzureCloudOptions,
13
+ PerformanceEvents,
14
+ AuthError,
15
+ } from "@azure/msal-common";
16
+ import { SilentRequest } from "../request/SilentRequest";
17
+ import { ApiId } from "../utils/BrowserConstants";
18
+ import {
19
+ BrowserAuthError,
20
+ BrowserAuthErrorCodes,
21
+ } from "../error/BrowserAuthError";
22
+ import { AuthenticationResult } from "../response/AuthenticationResult";
23
+ import { ClearCacheRequest } from "../request/ClearCacheRequest";
24
+
25
+ export class SilentCacheClient extends StandardInteractionClient {
26
+ /**
27
+ * Returns unexpired tokens from the cache, if available
28
+ * @param silentRequest
29
+ */
30
+ async acquireToken(
31
+ silentRequest: CommonSilentFlowRequest
32
+ ): Promise<AuthenticationResult> {
33
+ const acquireTokenMeasurement = this.performanceClient.startMeasurement(
34
+ PerformanceEvents.SilentCacheClientAcquireToken,
35
+ silentRequest.correlationId
36
+ );
37
+ // Telemetry manager only used to increment cacheHits here
38
+ const serverTelemetryManager = this.initializeServerTelemetryManager(
39
+ ApiId.acquireTokenSilent_silentFlow
40
+ );
41
+
42
+ const silentAuthClient = await this.createSilentFlowClient(
43
+ serverTelemetryManager,
44
+ silentRequest.authority,
45
+ silentRequest.azureCloudOptions
46
+ );
47
+ this.logger.verbose("Silent auth client created");
48
+
49
+ try {
50
+ const cachedToken = (await silentAuthClient.acquireCachedToken(
51
+ silentRequest
52
+ )) as AuthenticationResult;
53
+
54
+ acquireTokenMeasurement.end({
55
+ success: true,
56
+ fromCache: true,
57
+ });
58
+ return cachedToken;
59
+ } catch (error) {
60
+ if (
61
+ error instanceof BrowserAuthError &&
62
+ error.errorCode === BrowserAuthErrorCodes.cryptoKeyNotFound
63
+ ) {
64
+ this.logger.verbose(
65
+ "Signing keypair for bound access token not found. Refreshing bound access token and generating a new crypto keypair."
66
+ );
67
+ }
68
+ acquireTokenMeasurement.end({
69
+ errorCode:
70
+ (error instanceof AuthError && error.errorCode) ||
71
+ undefined,
72
+ subErrorCode:
73
+ (error instanceof AuthError && error.subError) || undefined,
74
+ success: false,
75
+ });
76
+ throw error;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * API to silenty clear the browser cache.
82
+ * @param logoutRequest
83
+ */
84
+ logout(logoutRequest?: ClearCacheRequest): Promise<void> {
85
+ this.logger.verbose("logoutRedirect called");
86
+ const validLogoutRequest = this.initializeLogoutRequest(logoutRequest);
87
+ return this.clearCacheOnLogout(validLogoutRequest?.account);
88
+ }
89
+
90
+ /**
91
+ * Creates an Silent Flow Client with the given authority, or the default authority.
92
+ * @param serverTelemetryManager
93
+ * @param authorityUrl
94
+ */
95
+ protected async createSilentFlowClient(
96
+ serverTelemetryManager: ServerTelemetryManager,
97
+ authorityUrl?: string,
98
+ azureCloudOptions?: AzureCloudOptions
99
+ ): Promise<SilentFlowClient> {
100
+ // Create auth module.
101
+ this.performanceClient.setPreQueueTime(
102
+ PerformanceEvents.StandardInteractionClientGetClientConfiguration,
103
+ this.correlationId
104
+ );
105
+ const clientConfig = await this.getClientConfiguration(
106
+ serverTelemetryManager,
107
+ authorityUrl,
108
+ azureCloudOptions
109
+ );
110
+ return new SilentFlowClient(clientConfig, this.performanceClient);
111
+ }
112
+
113
+ async initializeSilentRequest(
114
+ request: SilentRequest,
115
+ account: AccountInfo
116
+ ): Promise<CommonSilentFlowRequest> {
117
+ this.performanceClient.addQueueMeasurement(
118
+ PerformanceEvents.InitializeSilentRequest,
119
+ this.correlationId
120
+ );
121
+
122
+ this.performanceClient.setPreQueueTime(
123
+ PerformanceEvents.InitializeBaseRequest,
124
+ this.correlationId
125
+ );
126
+ return {
127
+ ...request,
128
+ ...(await this.initializeBaseRequest(request, account)),
129
+ account: account,
130
+ forceRefresh: request.forceRefresh || false,
131
+ };
132
+ }
133
+ }
@@ -0,0 +1,301 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ ICrypto,
8
+ Logger,
9
+ PromptValue,
10
+ CommonAuthorizationCodeRequest,
11
+ AuthorizationCodeClient,
12
+ AuthError,
13
+ Constants,
14
+ UrlString,
15
+ ServerAuthorizationCodeResponse,
16
+ ProtocolUtils,
17
+ IPerformanceClient,
18
+ PerformanceEvents,
19
+ invokeAsync,
20
+ } from "@azure/msal-common";
21
+ import { StandardInteractionClient } from "./StandardInteractionClient";
22
+ import { AuthorizationUrlRequest } from "../request/AuthorizationUrlRequest";
23
+ import { BrowserConfiguration } from "../config/Configuration";
24
+ import { BrowserCacheManager } from "../cache/BrowserCacheManager";
25
+ import { EventHandler } from "../event/EventHandler";
26
+ import { INavigationClient } from "../navigation/INavigationClient";
27
+ import {
28
+ createBrowserAuthError,
29
+ BrowserAuthErrorCodes,
30
+ } from "../error/BrowserAuthError";
31
+ import { InteractionType, ApiId } from "../utils/BrowserConstants";
32
+ import { SilentHandler } from "../interaction_handler/SilentHandler";
33
+ import { SsoSilentRequest } from "../request/SsoSilentRequest";
34
+ import { NativeMessageHandler } from "../broker/nativeBroker/NativeMessageHandler";
35
+ import { NativeInteractionClient } from "./NativeInteractionClient";
36
+ import { AuthenticationResult } from "../response/AuthenticationResult";
37
+
38
+ export class SilentIframeClient extends StandardInteractionClient {
39
+ protected apiId: ApiId;
40
+ protected nativeStorage: BrowserCacheManager;
41
+
42
+ constructor(
43
+ config: BrowserConfiguration,
44
+ storageImpl: BrowserCacheManager,
45
+ browserCrypto: ICrypto,
46
+ logger: Logger,
47
+ eventHandler: EventHandler,
48
+ navigationClient: INavigationClient,
49
+ apiId: ApiId,
50
+ performanceClient: IPerformanceClient,
51
+ nativeStorageImpl: BrowserCacheManager,
52
+ nativeMessageHandler?: NativeMessageHandler,
53
+ correlationId?: string
54
+ ) {
55
+ super(
56
+ config,
57
+ storageImpl,
58
+ browserCrypto,
59
+ logger,
60
+ eventHandler,
61
+ navigationClient,
62
+ performanceClient,
63
+ nativeMessageHandler,
64
+ correlationId
65
+ );
66
+ this.apiId = apiId;
67
+ this.nativeStorage = nativeStorageImpl;
68
+ }
69
+
70
+ /**
71
+ * Acquires a token silently by opening a hidden iframe to the /authorize endpoint with prompt=none or prompt=no_session
72
+ * @param request
73
+ */
74
+ async acquireToken(
75
+ request: SsoSilentRequest
76
+ ): Promise<AuthenticationResult> {
77
+ this.performanceClient.addQueueMeasurement(
78
+ PerformanceEvents.SilentIframeClientAcquireToken,
79
+ request.correlationId
80
+ );
81
+ // Check that we have some SSO data
82
+ if (
83
+ !request.loginHint &&
84
+ !request.sid &&
85
+ (!request.account || !request.account.username)
86
+ ) {
87
+ this.logger.warning(
88
+ "No user hint provided. The authorization server may need more information to complete this request."
89
+ );
90
+ }
91
+
92
+ // Check that prompt is set to none or no_session, throw error if it is set to anything else.
93
+ if (
94
+ request.prompt &&
95
+ request.prompt !== PromptValue.NONE &&
96
+ request.prompt !== PromptValue.NO_SESSION
97
+ ) {
98
+ throw createBrowserAuthError(
99
+ BrowserAuthErrorCodes.silentPromptValueError
100
+ );
101
+ }
102
+
103
+ // Create silent request
104
+ const silentRequest: AuthorizationUrlRequest = await invokeAsync(
105
+ this.initializeAuthorizationRequest.bind(this),
106
+ PerformanceEvents.StandardInteractionClientInitializeAuthorizationRequest,
107
+ this.logger,
108
+ this.performanceClient,
109
+ request.correlationId
110
+ )(
111
+ {
112
+ ...request,
113
+ prompt: request.prompt || PromptValue.NONE,
114
+ },
115
+ InteractionType.Silent
116
+ );
117
+ this.browserStorage.updateCacheEntries(
118
+ silentRequest.state,
119
+ silentRequest.nonce,
120
+ silentRequest.authority,
121
+ silentRequest.loginHint || Constants.EMPTY_STRING,
122
+ silentRequest.account || null
123
+ );
124
+
125
+ const serverTelemetryManager = this.initializeServerTelemetryManager(
126
+ this.apiId
127
+ );
128
+
129
+ try {
130
+ // Initialize the client
131
+ const authClient: AuthorizationCodeClient = await invokeAsync(
132
+ this.createAuthCodeClient.bind(this),
133
+ PerformanceEvents.StandardInteractionClientCreateAuthCodeClient,
134
+ this.logger,
135
+ this.performanceClient,
136
+ request.correlationId
137
+ )(
138
+ serverTelemetryManager,
139
+ silentRequest.authority,
140
+ silentRequest.azureCloudOptions
141
+ );
142
+
143
+ return await invokeAsync(
144
+ this.silentTokenHelper.bind(this),
145
+ PerformanceEvents.SilentIframeClientTokenHelper,
146
+ this.logger,
147
+ this.performanceClient,
148
+ request.correlationId
149
+ )(authClient, silentRequest);
150
+ } catch (e) {
151
+ if (e instanceof AuthError) {
152
+ (e as AuthError).setCorrelationId(this.correlationId);
153
+ serverTelemetryManager.cacheFailedRequest(e);
154
+ }
155
+ this.browserStorage.cleanRequestByState(silentRequest.state);
156
+ throw e;
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Currently Unsupported
162
+ */
163
+ logout(): Promise<void> {
164
+ // Synchronous so we must reject
165
+ return Promise.reject(
166
+ createBrowserAuthError(
167
+ BrowserAuthErrorCodes.silentLogoutUnsupported
168
+ )
169
+ );
170
+ }
171
+
172
+ /**
173
+ * Helper which acquires an authorization code silently using a hidden iframe from given url
174
+ * using the scopes requested as part of the id, and exchanges the code for a set of OAuth tokens.
175
+ * @param navigateUrl
176
+ * @param userRequestScopes
177
+ */
178
+ protected async silentTokenHelper(
179
+ authClient: AuthorizationCodeClient,
180
+ silentRequest: AuthorizationUrlRequest
181
+ ): Promise<AuthenticationResult> {
182
+ this.performanceClient.addQueueMeasurement(
183
+ PerformanceEvents.SilentIframeClientTokenHelper,
184
+ silentRequest.correlationId
185
+ );
186
+
187
+ // Create auth code request and generate PKCE params
188
+ const authCodeRequest: CommonAuthorizationCodeRequest =
189
+ await invokeAsync(
190
+ this.initializeAuthorizationCodeRequest.bind(this),
191
+ PerformanceEvents.StandardInteractionClientInitializeAuthorizationCodeRequest,
192
+ this.logger,
193
+ this.performanceClient,
194
+ silentRequest.correlationId
195
+ )(silentRequest);
196
+
197
+ // Create authorize request url
198
+ const navigateUrl = await invokeAsync(
199
+ authClient.getAuthCodeUrl.bind(authClient),
200
+ PerformanceEvents.GetAuthCodeUrl,
201
+ this.logger,
202
+ this.performanceClient,
203
+ silentRequest.correlationId
204
+ )({
205
+ ...silentRequest,
206
+ nativeBroker: NativeMessageHandler.isNativeAvailable(
207
+ this.config,
208
+ this.logger,
209
+ this.nativeMessageHandler,
210
+ silentRequest.authenticationScheme
211
+ ),
212
+ });
213
+
214
+ // Create silent handler
215
+ const silentHandler = new SilentHandler(
216
+ authClient,
217
+ this.browserStorage,
218
+ authCodeRequest,
219
+ this.logger,
220
+ this.config.system,
221
+ this.performanceClient
222
+ );
223
+ // Get the frame handle for the silent request
224
+ const msalFrame = await invokeAsync(
225
+ silentHandler.initiateAuthRequest.bind(silentHandler),
226
+ PerformanceEvents.SilentHandlerInitiateAuthRequest,
227
+ this.logger,
228
+ this.performanceClient,
229
+ silentRequest.correlationId
230
+ )(navigateUrl);
231
+ // Monitor the window for the hash. Return the string value and close the popup when the hash is received. Default timeout is 60 seconds.
232
+ const hash = await invokeAsync(
233
+ silentHandler.monitorIframeForHash.bind(silentHandler),
234
+ PerformanceEvents.SilentHandlerInitiateAuthRequest,
235
+ this.logger,
236
+ this.performanceClient,
237
+ silentRequest.correlationId
238
+ )(msalFrame, this.config.system.iframeHashTimeout);
239
+ // Deserialize hash fragment response parameters.
240
+ const serverParams: ServerAuthorizationCodeResponse =
241
+ UrlString.getDeserializedHash(hash);
242
+ const state = this.validateAndExtractStateFromHash(
243
+ serverParams,
244
+ InteractionType.Silent,
245
+ authCodeRequest.correlationId
246
+ );
247
+
248
+ if (serverParams.accountId) {
249
+ this.logger.verbose(
250
+ "Account id found in hash, calling WAM for token"
251
+ );
252
+ if (!this.nativeMessageHandler) {
253
+ throw createBrowserAuthError(
254
+ BrowserAuthErrorCodes.nativeConnectionNotEstablished
255
+ );
256
+ }
257
+ const nativeInteractionClient = new NativeInteractionClient(
258
+ this.config,
259
+ this.browserStorage,
260
+ this.browserCrypto,
261
+ this.logger,
262
+ this.eventHandler,
263
+ this.navigationClient,
264
+ this.apiId,
265
+ this.performanceClient,
266
+ this.nativeMessageHandler,
267
+ serverParams.accountId,
268
+ this.browserStorage,
269
+ this.correlationId
270
+ );
271
+ const { userRequestState } = ProtocolUtils.parseRequestState(
272
+ this.browserCrypto,
273
+ state
274
+ );
275
+ return invokeAsync(
276
+ nativeInteractionClient.acquireToken.bind(
277
+ nativeInteractionClient
278
+ ),
279
+ PerformanceEvents.NativeInteractionClientAcquireToken,
280
+ this.logger,
281
+ this.performanceClient,
282
+ silentRequest.correlationId
283
+ )({
284
+ ...silentRequest,
285
+ state: userRequestState,
286
+ prompt: silentRequest.prompt || PromptValue.NONE,
287
+ }).finally(() => {
288
+ this.browserStorage.cleanRequestByState(state);
289
+ });
290
+ }
291
+
292
+ // Handle response from hash string
293
+ return invokeAsync(
294
+ silentHandler.handleCodeResponseFromHash.bind(silentHandler),
295
+ PerformanceEvents.HandleCodeResponseFromHash,
296
+ this.logger,
297
+ this.performanceClient,
298
+ silentRequest.correlationId
299
+ )(hash, state, authClient.authority, this.networkClient);
300
+ }
301
+ }