@azure/msal-browser 3.0.2 → 3.2.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 (280) hide show
  1. package/dist/app/IPublicClientApplication.d.ts +2 -0
  2. package/dist/app/IPublicClientApplication.d.ts.map +1 -1
  3. package/dist/app/IPublicClientApplication.mjs +22 -18
  4. package/dist/app/IPublicClientApplication.mjs.map +1 -1
  5. package/dist/app/PublicClientApplication.d.ts +20 -6
  6. package/dist/app/PublicClientApplication.d.ts.map +1 -1
  7. package/dist/app/PublicClientApplication.mjs +24 -7
  8. package/dist/app/PublicClientApplication.mjs.map +1 -1
  9. package/dist/broker/nativeBroker/NativeMessageHandler.d.ts +3 -4
  10. package/dist/broker/nativeBroker/NativeMessageHandler.d.ts.map +1 -1
  11. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +17 -16
  12. package/dist/broker/nativeBroker/NativeMessageHandler.mjs.map +1 -1
  13. package/dist/broker/nativeBroker/NativeStatusCodes.d.ts +8 -0
  14. package/dist/broker/nativeBroker/NativeStatusCodes.d.ts.map +1 -0
  15. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +16 -0
  16. package/dist/broker/nativeBroker/NativeStatusCodes.mjs.map +1 -0
  17. package/dist/cache/AsyncMemoryStorage.mjs +4 -3
  18. package/dist/cache/AsyncMemoryStorage.mjs.map +1 -1
  19. package/dist/cache/BrowserCacheManager.d.ts +10 -3
  20. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  21. package/dist/cache/BrowserCacheManager.mjs +58 -29
  22. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  23. package/dist/cache/BrowserStorage.d.ts.map +1 -1
  24. package/dist/cache/BrowserStorage.mjs +7 -9
  25. package/dist/cache/BrowserStorage.mjs.map +1 -1
  26. package/dist/cache/CryptoKeyStore.mjs +1 -1
  27. package/dist/cache/CryptoKeyStore.mjs.map +1 -1
  28. package/dist/cache/DatabaseStorage.d.ts.map +1 -1
  29. package/dist/cache/DatabaseStorage.mjs +9 -8
  30. package/dist/cache/DatabaseStorage.mjs.map +1 -1
  31. package/dist/cache/MemoryStorage.mjs +1 -1
  32. package/dist/cache/MemoryStorage.mjs.map +1 -1
  33. package/dist/cache/TokenCache.d.ts.map +1 -1
  34. package/dist/cache/TokenCache.mjs +30 -30
  35. package/dist/cache/TokenCache.mjs.map +1 -1
  36. package/dist/config/Configuration.d.ts +1 -0
  37. package/dist/config/Configuration.d.ts.map +1 -1
  38. package/dist/config/Configuration.mjs +12 -16
  39. package/dist/config/Configuration.mjs.map +1 -1
  40. package/dist/controllers/ControllerFactory.mjs +1 -1
  41. package/dist/controllers/ControllerFactory.mjs.map +1 -1
  42. package/dist/controllers/IController.d.ts +5 -28
  43. package/dist/controllers/IController.d.ts.map +1 -1
  44. package/dist/controllers/StandardController.d.ts +17 -31
  45. package/dist/controllers/StandardController.d.ts.map +1 -1
  46. package/dist/controllers/StandardController.mjs +78 -83
  47. package/dist/controllers/StandardController.mjs.map +1 -1
  48. package/dist/crypto/BrowserCrypto.d.ts +44 -49
  49. package/dist/crypto/BrowserCrypto.d.ts.map +1 -1
  50. package/dist/crypto/BrowserCrypto.mjs +78 -77
  51. package/dist/crypto/BrowserCrypto.mjs.map +1 -1
  52. package/dist/crypto/CryptoOps.d.ts +1 -10
  53. package/dist/crypto/CryptoOps.d.ts.map +1 -1
  54. package/dist/crypto/CryptoOps.mjs +23 -34
  55. package/dist/crypto/CryptoOps.mjs.map +1 -1
  56. package/dist/crypto/PkceGenerator.d.ts +6 -22
  57. package/dist/crypto/PkceGenerator.d.ts.map +1 -1
  58. package/dist/crypto/PkceGenerator.mjs +48 -49
  59. package/dist/crypto/PkceGenerator.mjs.map +1 -1
  60. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  61. package/dist/crypto/SignedHttpRequest.mjs.map +1 -1
  62. package/dist/encode/Base64Decode.d.ts +6 -19
  63. package/dist/encode/Base64Decode.d.ts.map +1 -1
  64. package/dist/encode/Base64Decode.mjs +31 -68
  65. package/dist/encode/Base64Decode.mjs.map +1 -1
  66. package/dist/encode/Base64Encode.d.ts +15 -27
  67. package/dist/encode/Base64Encode.d.ts.map +1 -1
  68. package/dist/encode/Base64Encode.mjs +36 -75
  69. package/dist/encode/Base64Encode.mjs.map +1 -1
  70. package/dist/error/BrowserAuthError.d.ts +63 -195
  71. package/dist/error/BrowserAuthError.d.ts.map +1 -1
  72. package/dist/error/BrowserAuthError.mjs +159 -381
  73. package/dist/error/BrowserAuthError.mjs.map +1 -1
  74. package/dist/error/BrowserAuthErrorCodes.d.ts +46 -0
  75. package/dist/error/BrowserAuthErrorCodes.d.ts.map +1 -0
  76. package/dist/error/BrowserAuthErrorCodes.mjs +54 -0
  77. package/dist/error/BrowserAuthErrorCodes.mjs.map +1 -0
  78. package/dist/error/BrowserConfigurationAuthError.d.ts +9 -46
  79. package/dist/error/BrowserConfigurationAuthError.d.ts.map +1 -1
  80. package/dist/error/BrowserConfigurationAuthError.mjs +20 -73
  81. package/dist/error/BrowserConfigurationAuthError.mjs.map +1 -1
  82. package/dist/error/BrowserConfigurationAuthErrorCodes.d.ts +4 -0
  83. package/dist/error/BrowserConfigurationAuthErrorCodes.d.ts.map +1 -0
  84. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +12 -0
  85. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs.map +1 -0
  86. package/dist/error/NativeAuthError.d.ts +17 -45
  87. package/dist/error/NativeAuthError.d.ts.map +1 -1
  88. package/dist/error/NativeAuthError.mjs +49 -79
  89. package/dist/error/NativeAuthError.mjs.map +1 -1
  90. package/dist/error/NativeAuthErrorCodes.d.ts +3 -0
  91. package/dist/error/NativeAuthErrorCodes.d.ts.map +1 -0
  92. package/dist/error/NativeAuthErrorCodes.mjs +11 -0
  93. package/dist/error/NativeAuthErrorCodes.mjs.map +1 -0
  94. package/dist/event/EventHandler.d.ts.map +1 -1
  95. package/dist/event/EventHandler.mjs +3 -2
  96. package/dist/event/EventHandler.mjs.map +1 -1
  97. package/dist/event/EventMessage.mjs +1 -1
  98. package/dist/event/EventMessage.mjs.map +1 -1
  99. package/dist/event/EventType.mjs +1 -1
  100. package/dist/event/EventType.mjs.map +1 -1
  101. package/dist/index.d.ts +6 -6
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.mjs +8 -4
  104. package/dist/index.mjs.map +1 -1
  105. package/dist/interaction_client/BaseInteractionClient.d.ts +2 -1
  106. package/dist/interaction_client/BaseInteractionClient.d.ts.map +1 -1
  107. package/dist/interaction_client/BaseInteractionClient.mjs +7 -8
  108. package/dist/interaction_client/BaseInteractionClient.mjs.map +1 -1
  109. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  110. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs.map +1 -1
  111. package/dist/interaction_client/NativeInteractionClient.d.ts +4 -10
  112. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  113. package/dist/interaction_client/NativeInteractionClient.mjs +32 -38
  114. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  115. package/dist/interaction_client/PopupClient.d.ts.map +1 -1
  116. package/dist/interaction_client/PopupClient.mjs +16 -15
  117. package/dist/interaction_client/PopupClient.mjs.map +1 -1
  118. package/dist/interaction_client/RedirectClient.d.ts.map +1 -1
  119. package/dist/interaction_client/RedirectClient.mjs +7 -6
  120. package/dist/interaction_client/RedirectClient.mjs.map +1 -1
  121. package/dist/interaction_client/SilentAuthCodeClient.d.ts.map +1 -1
  122. package/dist/interaction_client/SilentAuthCodeClient.mjs +9 -11
  123. package/dist/interaction_client/SilentAuthCodeClient.mjs.map +1 -1
  124. package/dist/interaction_client/SilentCacheClient.d.ts +4 -2
  125. package/dist/interaction_client/SilentCacheClient.d.ts.map +1 -1
  126. package/dist/interaction_client/SilentCacheClient.mjs +19 -25
  127. package/dist/interaction_client/SilentCacheClient.mjs.map +1 -1
  128. package/dist/interaction_client/SilentIframeClient.d.ts.map +1 -1
  129. package/dist/interaction_client/SilentIframeClient.mjs +20 -47
  130. package/dist/interaction_client/SilentIframeClient.mjs.map +1 -1
  131. package/dist/interaction_client/SilentRefreshClient.d.ts.map +1 -1
  132. package/dist/interaction_client/SilentRefreshClient.mjs +11 -20
  133. package/dist/interaction_client/SilentRefreshClient.mjs.map +1 -1
  134. package/dist/interaction_client/StandardInteractionClient.d.ts.map +1 -1
  135. package/dist/interaction_client/StandardInteractionClient.mjs +18 -38
  136. package/dist/interaction_client/StandardInteractionClient.mjs.map +1 -1
  137. package/dist/interaction_handler/InteractionHandler.d.ts.map +1 -1
  138. package/dist/interaction_handler/InteractionHandler.mjs +13 -16
  139. package/dist/interaction_handler/InteractionHandler.mjs.map +1 -1
  140. package/dist/interaction_handler/RedirectHandler.d.ts.map +1 -1
  141. package/dist/interaction_handler/RedirectHandler.mjs +12 -11
  142. package/dist/interaction_handler/RedirectHandler.mjs.map +1 -1
  143. package/dist/interaction_handler/SilentHandler.d.ts.map +1 -1
  144. package/dist/interaction_handler/SilentHandler.mjs +11 -11
  145. package/dist/interaction_handler/SilentHandler.mjs.map +1 -1
  146. package/dist/navigation/NavigationClient.mjs +1 -1
  147. package/dist/navigation/NavigationClient.mjs.map +1 -1
  148. package/dist/network/FetchClient.d.ts.map +1 -1
  149. package/dist/network/FetchClient.mjs +9 -8
  150. package/dist/network/FetchClient.mjs.map +1 -1
  151. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  152. package/dist/operatingcontext/BaseOperatingContext.mjs.map +1 -1
  153. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  154. package/dist/operatingcontext/StandardOperatingContext.mjs.map +1 -1
  155. package/dist/operatingcontext/TeamsAppOperatingContext.mjs +1 -1
  156. package/dist/operatingcontext/TeamsAppOperatingContext.mjs.map +1 -1
  157. package/dist/packageMetadata.d.ts +1 -1
  158. package/dist/packageMetadata.mjs +2 -2
  159. package/dist/packageMetadata.mjs.map +1 -1
  160. package/dist/request/ClearCacheRequest.d.ts +11 -0
  161. package/dist/request/ClearCacheRequest.d.ts.map +1 -0
  162. package/dist/telemetry/BrowserPerformanceClient.d.ts +2 -4
  163. package/dist/telemetry/BrowserPerformanceClient.d.ts.map +1 -1
  164. package/dist/telemetry/BrowserPerformanceClient.mjs +2 -6
  165. package/dist/telemetry/BrowserPerformanceClient.mjs.map +1 -1
  166. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  167. package/dist/telemetry/BrowserPerformanceMeasurement.mjs.map +1 -1
  168. package/dist/utils/BrowserConstants.mjs +1 -1
  169. package/dist/utils/BrowserConstants.mjs.map +1 -1
  170. package/dist/utils/BrowserProtocolUtils.d.ts.map +1 -1
  171. package/dist/utils/BrowserProtocolUtils.mjs +4 -4
  172. package/dist/utils/BrowserProtocolUtils.mjs.map +1 -1
  173. package/dist/utils/BrowserStringUtils.mjs +1 -1
  174. package/dist/utils/BrowserStringUtils.mjs.map +1 -1
  175. package/dist/utils/BrowserUtils.d.ts +0 -9
  176. package/dist/utils/BrowserUtils.d.ts.map +1 -1
  177. package/dist/utils/BrowserUtils.mjs +8 -33
  178. package/dist/utils/BrowserUtils.mjs.map +1 -1
  179. package/lib/msal-browser.cjs +8729 -9566
  180. package/lib/msal-browser.cjs.map +1 -1
  181. package/lib/msal-browser.js +8729 -9566
  182. package/lib/msal-browser.js.map +1 -1
  183. package/lib/msal-browser.min.js +68 -62
  184. package/package.json +7 -5
  185. package/src/app/IPublicClientApplication.ts +236 -0
  186. package/src/app/PublicClientApplication.ts +417 -0
  187. package/src/broker/nativeBroker/NativeMessageHandler.ts +416 -0
  188. package/src/broker/nativeBroker/NativeRequest.ts +52 -0
  189. package/src/broker/nativeBroker/NativeResponse.ts +56 -0
  190. package/src/broker/nativeBroker/NativeStatusCodes.ts +13 -0
  191. package/src/cache/AsyncMemoryStorage.ts +158 -0
  192. package/src/cache/BrowserCacheManager.ts +2009 -0
  193. package/src/cache/BrowserStorage.ts +52 -0
  194. package/src/cache/CryptoKeyStore.ts +63 -0
  195. package/src/cache/DatabaseStorage.ts +287 -0
  196. package/src/cache/IAsyncMemoryStorage.ts +36 -0
  197. package/src/cache/ITokenCache.ts +21 -0
  198. package/src/cache/IWindowStorage.ts +36 -0
  199. package/src/cache/MemoryStorage.ts +42 -0
  200. package/src/cache/TokenCache.ts +484 -0
  201. package/src/config/Configuration.ts +383 -0
  202. package/src/controllers/ControllerFactory.ts +55 -0
  203. package/src/controllers/IController.ts +134 -0
  204. package/src/controllers/StandardController.ts +2170 -0
  205. package/src/crypto/BrowserCrypto.ts +151 -0
  206. package/src/crypto/CryptoOps.ts +235 -0
  207. package/src/crypto/PkceGenerator.ts +115 -0
  208. package/src/crypto/SignedHttpRequest.ts +76 -0
  209. package/src/encode/Base64Decode.ts +46 -0
  210. package/src/encode/Base64Encode.ts +52 -0
  211. package/src/error/BrowserAuthError.ts +352 -0
  212. package/src/error/BrowserAuthErrorCodes.ts +57 -0
  213. package/src/error/BrowserConfigurationAuthError.ts +64 -0
  214. package/src/error/BrowserConfigurationAuthErrorCodes.ts +9 -0
  215. package/src/error/NativeAuthError.ts +113 -0
  216. package/src/error/NativeAuthErrorCodes.ts +7 -0
  217. package/src/event/EventHandler.ts +177 -0
  218. package/src/event/EventMessage.ts +125 -0
  219. package/src/event/EventType.ts +33 -0
  220. package/src/index.ts +157 -0
  221. package/src/interaction_client/BaseInteractionClient.ts +307 -0
  222. package/src/interaction_client/HybridSpaAuthorizationCodeClient.ts +16 -0
  223. package/src/interaction_client/NativeInteractionClient.ts +925 -0
  224. package/src/interaction_client/PopupClient.ts +926 -0
  225. package/src/interaction_client/RedirectClient.ts +616 -0
  226. package/src/interaction_client/SilentAuthCodeClient.ts +165 -0
  227. package/src/interaction_client/SilentCacheClient.ts +125 -0
  228. package/src/interaction_client/SilentIframeClient.ts +301 -0
  229. package/src/interaction_client/SilentRefreshClient.ts +118 -0
  230. package/src/interaction_client/StandardInteractionClient.ts +450 -0
  231. package/src/interaction_handler/InteractionHandler.ts +251 -0
  232. package/src/interaction_handler/RedirectHandler.ts +229 -0
  233. package/src/interaction_handler/SilentHandler.ts +269 -0
  234. package/src/navigation/INavigationClient.ts +23 -0
  235. package/src/navigation/NavigationClient.ts +55 -0
  236. package/src/navigation/NavigationOptions.ts +18 -0
  237. package/src/network/FetchClient.ts +130 -0
  238. package/src/operatingcontext/BaseOperatingContext.ts +82 -0
  239. package/src/operatingcontext/StandardOperatingContext.ts +49 -0
  240. package/src/operatingcontext/TeamsAppOperatingContext.ts +48 -0
  241. package/src/packageMetadata.ts +3 -0
  242. package/src/request/AuthorizationCodeRequest.ts +19 -0
  243. package/src/request/AuthorizationUrlRequest.ts +17 -0
  244. package/src/request/ClearCacheRequest.ts +16 -0
  245. package/src/request/EndSessionPopupRequest.ts +26 -0
  246. package/src/request/EndSessionRequest.ts +23 -0
  247. package/src/request/PopupRequest.ts +51 -0
  248. package/src/request/PopupWindowAttributes.ts +22 -0
  249. package/src/request/RedirectRequest.ts +51 -0
  250. package/src/request/SilentRequest.ts +49 -0
  251. package/src/request/SsoSilentRequest.ts +44 -0
  252. package/src/response/AuthenticationResult.ts +13 -0
  253. package/src/telemetry/BrowserPerformanceClient.ts +226 -0
  254. package/src/telemetry/BrowserPerformanceMeasurement.ts +144 -0
  255. package/src/utils/BrowserConstants.ts +241 -0
  256. package/src/utils/BrowserProtocolUtils.ts +58 -0
  257. package/src/utils/BrowserStringUtils.ts +143 -0
  258. package/src/utils/BrowserUtils.ts +156 -0
  259. package/dist/crypto/GuidGenerator.d.ts +0 -13
  260. package/dist/crypto/GuidGenerator.d.ts.map +0 -1
  261. package/dist/crypto/GuidGenerator.mjs +0 -104
  262. package/dist/crypto/GuidGenerator.mjs.map +0 -1
  263. package/dist/crypto/ISubtleCrypto.d.ts +0 -10
  264. package/dist/crypto/ISubtleCrypto.d.ts.map +0 -1
  265. package/dist/crypto/ModernBrowserCrypto.d.ts +0 -10
  266. package/dist/crypto/ModernBrowserCrypto.d.ts.map +0 -1
  267. package/dist/crypto/ModernBrowserCrypto.mjs +0 -31
  268. package/dist/crypto/ModernBrowserCrypto.mjs.map +0 -1
  269. package/dist/internals.d.ts +0 -23
  270. package/dist/internals.d.ts.map +0 -1
  271. package/dist/internals.mjs +0 -28
  272. package/dist/internals.mjs.map +0 -1
  273. package/dist/network/XhrClient.d.ts +0 -41
  274. package/dist/network/XhrClient.d.ts.map +0 -1
  275. package/dist/network/XhrClient.mjs +0 -125
  276. package/dist/network/XhrClient.mjs.map +0 -1
  277. package/dist/utils/MathUtils.d.ts +0 -12
  278. package/dist/utils/MathUtils.d.ts.map +0 -1
  279. package/dist/utils/MathUtils.mjs +0 -26
  280. package/dist/utils/MathUtils.mjs.map +0 -1
@@ -0,0 +1,925 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ Logger,
8
+ ICrypto,
9
+ PromptValue,
10
+ AuthToken,
11
+ Constants,
12
+ AccountEntity,
13
+ AuthorityType,
14
+ ScopeSet,
15
+ TimeUtils,
16
+ AuthenticationScheme,
17
+ UrlString,
18
+ OIDC_DEFAULT_SCOPES,
19
+ PopTokenGenerator,
20
+ SignedHttpRequestParameters,
21
+ IPerformanceClient,
22
+ PerformanceEvents,
23
+ IdTokenEntity,
24
+ AccessTokenEntity,
25
+ AuthError,
26
+ CommonSilentFlowRequest,
27
+ AccountInfo,
28
+ CacheRecord,
29
+ AADServerParamKeys,
30
+ TokenClaims,
31
+ createClientAuthError,
32
+ ClientAuthErrorCodes,
33
+ invokeAsync,
34
+ createAuthError,
35
+ AuthErrorCodes,
36
+ } from "@azure/msal-common";
37
+ import { BaseInteractionClient } from "./BaseInteractionClient";
38
+ import { BrowserConfiguration } from "../config/Configuration";
39
+ import { BrowserCacheManager } from "../cache/BrowserCacheManager";
40
+ import { EventHandler } from "../event/EventHandler";
41
+ import { PopupRequest } from "../request/PopupRequest";
42
+ import { SilentRequest } from "../request/SilentRequest";
43
+ import { SsoSilentRequest } from "../request/SsoSilentRequest";
44
+ import { NativeMessageHandler } from "../broker/nativeBroker/NativeMessageHandler";
45
+ import {
46
+ NativeExtensionMethod,
47
+ ApiId,
48
+ TemporaryCacheKeys,
49
+ NativeConstants,
50
+ } from "../utils/BrowserConstants";
51
+ import {
52
+ NativeExtensionRequestBody,
53
+ NativeTokenRequest,
54
+ } from "../broker/nativeBroker/NativeRequest";
55
+ import { MATS, NativeResponse } from "../broker/nativeBroker/NativeResponse";
56
+ import {
57
+ NativeAuthError,
58
+ NativeAuthErrorCodes,
59
+ createNativeAuthError,
60
+ isFatalNativeAuthError,
61
+ } from "../error/NativeAuthError";
62
+ import { RedirectRequest } from "../request/RedirectRequest";
63
+ import { NavigationOptions } from "../navigation/NavigationOptions";
64
+ import { INavigationClient } from "../navigation/INavigationClient";
65
+ import {
66
+ createBrowserAuthError,
67
+ BrowserAuthErrorCodes,
68
+ } from "../error/BrowserAuthError";
69
+ import { SilentCacheClient } from "./SilentCacheClient";
70
+ import { AuthenticationResult } from "../response/AuthenticationResult";
71
+ import { base64Decode } from "../encode/Base64Decode";
72
+
73
+ const BrokerServerParamKeys = {
74
+ BROKER_CLIENT_ID: "brk_client_id",
75
+ BROKER_REDIRECT_URI: "brk_redirect_uri",
76
+ };
77
+
78
+ export class NativeInteractionClient extends BaseInteractionClient {
79
+ protected apiId: ApiId;
80
+ protected accountId: string;
81
+ protected nativeMessageHandler: NativeMessageHandler;
82
+ protected silentCacheClient: SilentCacheClient;
83
+ protected nativeStorageManager: BrowserCacheManager;
84
+
85
+ constructor(
86
+ config: BrowserConfiguration,
87
+ browserStorage: BrowserCacheManager,
88
+ browserCrypto: ICrypto,
89
+ logger: Logger,
90
+ eventHandler: EventHandler,
91
+ navigationClient: INavigationClient,
92
+ apiId: ApiId,
93
+ performanceClient: IPerformanceClient,
94
+ provider: NativeMessageHandler,
95
+ accountId: string,
96
+ nativeStorageImpl: BrowserCacheManager,
97
+ correlationId?: string
98
+ ) {
99
+ super(
100
+ config,
101
+ browserStorage,
102
+ browserCrypto,
103
+ logger,
104
+ eventHandler,
105
+ navigationClient,
106
+ performanceClient,
107
+ provider,
108
+ correlationId
109
+ );
110
+ this.apiId = apiId;
111
+ this.accountId = accountId;
112
+ this.nativeMessageHandler = provider;
113
+ this.nativeStorageManager = nativeStorageImpl;
114
+ this.silentCacheClient = new SilentCacheClient(
115
+ config,
116
+ this.nativeStorageManager,
117
+ browserCrypto,
118
+ logger,
119
+ eventHandler,
120
+ navigationClient,
121
+ performanceClient,
122
+ provider,
123
+ correlationId
124
+ );
125
+ }
126
+
127
+ /**
128
+ * Acquire token from native platform via browser extension
129
+ * @param request
130
+ */
131
+ async acquireToken(
132
+ request: PopupRequest | SilentRequest | SsoSilentRequest
133
+ ): Promise<AuthenticationResult> {
134
+ this.performanceClient.addQueueMeasurement(
135
+ PerformanceEvents.NativeInteractionClientAcquireToken,
136
+ request.correlationId
137
+ );
138
+ this.logger.trace("NativeInteractionClient - acquireToken called.");
139
+
140
+ // start the perf measurement
141
+ const nativeATMeasurement = this.performanceClient.startMeasurement(
142
+ PerformanceEvents.NativeInteractionClientAcquireToken,
143
+ request.correlationId
144
+ );
145
+ const reqTimestamp = TimeUtils.nowSeconds();
146
+
147
+ // initialize native request
148
+ const nativeRequest = await this.initializeNativeRequest(request);
149
+
150
+ // check if the tokens can be retrieved from internal cache
151
+ try {
152
+ const result = await this.acquireTokensFromCache(
153
+ this.accountId,
154
+ nativeRequest
155
+ );
156
+ nativeATMeasurement.end({
157
+ success: true,
158
+ isNativeBroker: false, // Should be true only when the result is coming directly from the broker
159
+ fromCache: true,
160
+ });
161
+ return result;
162
+ } catch (e) {
163
+ // continue with a native call for any and all errors
164
+ this.logger.info(
165
+ "MSAL internal Cache does not contain tokens, proceed to make a native call"
166
+ );
167
+ }
168
+
169
+ // fall back to native calls
170
+ const messageBody: NativeExtensionRequestBody = {
171
+ method: NativeExtensionMethod.GetToken,
172
+ request: nativeRequest,
173
+ };
174
+
175
+ const response: object = await this.nativeMessageHandler.sendMessage(
176
+ messageBody
177
+ );
178
+ const validatedResponse: NativeResponse =
179
+ this.validateNativeResponse(response);
180
+
181
+ return this.handleNativeResponse(
182
+ validatedResponse,
183
+ nativeRequest,
184
+ reqTimestamp
185
+ )
186
+ .then((result: AuthenticationResult) => {
187
+ nativeATMeasurement.end({
188
+ success: true,
189
+ isNativeBroker: true,
190
+ requestId: result.requestId,
191
+ });
192
+ return result;
193
+ })
194
+ .catch((error: AuthError) => {
195
+ nativeATMeasurement.end({
196
+ success: false,
197
+ errorCode: error.errorCode,
198
+ subErrorCode: error.subError,
199
+ isNativeBroker: true,
200
+ });
201
+ throw error;
202
+ });
203
+ }
204
+
205
+ /**
206
+ * Creates silent flow request
207
+ * @param request
208
+ * @param cachedAccount
209
+ * @returns CommonSilentFlowRequest
210
+ */
211
+ private createSilentCacheRequest(
212
+ request: NativeTokenRequest,
213
+ cachedAccount: AccountInfo
214
+ ): CommonSilentFlowRequest {
215
+ return {
216
+ authority: request.authority,
217
+ correlationId: this.correlationId,
218
+ scopes: ScopeSet.fromString(request.scope).asArray(),
219
+ account: cachedAccount,
220
+ forceRefresh: false,
221
+ };
222
+ }
223
+
224
+ /**
225
+ * Fetches the tokens from the cache if un-expired
226
+ * @param nativeAccountId
227
+ * @param request
228
+ * @returns authenticationResult
229
+ */
230
+ protected async acquireTokensFromCache(
231
+ nativeAccountId: string,
232
+ request: NativeTokenRequest
233
+ ): Promise<AuthenticationResult> {
234
+ if (!nativeAccountId) {
235
+ this.logger.warning(
236
+ "NativeInteractionClient:acquireTokensFromCache - No nativeAccountId provided"
237
+ );
238
+ throw createClientAuthError(ClientAuthErrorCodes.noAccountFound);
239
+ }
240
+ // fetch the account from browser cache
241
+ const account = this.browserStorage.getAccountInfoFilteredBy({
242
+ nativeAccountId,
243
+ });
244
+ if (!account) {
245
+ throw createClientAuthError(ClientAuthErrorCodes.noAccountFound);
246
+ }
247
+
248
+ // leverage silent flow for cached tokens retrieval
249
+ try {
250
+ const silentRequest = this.createSilentCacheRequest(
251
+ request,
252
+ account
253
+ );
254
+ const result = await this.silentCacheClient.acquireToken(
255
+ silentRequest
256
+ );
257
+ return {
258
+ ...result,
259
+ account,
260
+ };
261
+ } catch (e) {
262
+ throw e;
263
+ }
264
+ }
265
+
266
+ /**
267
+ * Acquires a token from native platform then redirects to the redirectUri instead of returning the response
268
+ * @param request
269
+ */
270
+ async acquireTokenRedirect(request: RedirectRequest): Promise<void> {
271
+ this.logger.trace(
272
+ "NativeInteractionClient - acquireTokenRedirect called."
273
+ );
274
+ const nativeRequest = await this.initializeNativeRequest(request);
275
+
276
+ const messageBody: NativeExtensionRequestBody = {
277
+ method: NativeExtensionMethod.GetToken,
278
+ request: nativeRequest,
279
+ };
280
+
281
+ try {
282
+ const response: object =
283
+ await this.nativeMessageHandler.sendMessage(messageBody);
284
+ this.validateNativeResponse(response);
285
+ } catch (e) {
286
+ // Only throw fatal errors here to allow application to fallback to regular redirect. Otherwise proceed and the error will be thrown in handleRedirectPromise
287
+ if (e instanceof NativeAuthError && isFatalNativeAuthError(e)) {
288
+ throw e;
289
+ }
290
+ }
291
+ this.browserStorage.setTemporaryCache(
292
+ TemporaryCacheKeys.NATIVE_REQUEST,
293
+ JSON.stringify(nativeRequest),
294
+ true
295
+ );
296
+
297
+ const navigationOptions: NavigationOptions = {
298
+ apiId: ApiId.acquireTokenRedirect,
299
+ timeout: this.config.system.redirectNavigationTimeout,
300
+ noHistory: false,
301
+ };
302
+ const redirectUri = this.config.auth.navigateToLoginRequestUrl
303
+ ? window.location.href
304
+ : this.getRedirectUri(request.redirectUri);
305
+ await this.navigationClient.navigateExternal(
306
+ redirectUri,
307
+ navigationOptions
308
+ ); // Need to treat this as external to ensure handleRedirectPromise is run again
309
+ }
310
+
311
+ /**
312
+ * If the previous page called native platform for a token using redirect APIs, send the same request again and return the response
313
+ */
314
+ async handleRedirectPromise(): Promise<AuthenticationResult | null> {
315
+ this.logger.trace(
316
+ "NativeInteractionClient - handleRedirectPromise called."
317
+ );
318
+ if (!this.browserStorage.isInteractionInProgress(true)) {
319
+ this.logger.info(
320
+ "handleRedirectPromise called but there is no interaction in progress, returning null."
321
+ );
322
+ return null;
323
+ }
324
+
325
+ // remove prompt from the request to prevent WAM from prompting twice
326
+ const cachedRequest = this.browserStorage.getCachedNativeRequest();
327
+ if (!cachedRequest) {
328
+ this.logger.verbose(
329
+ "NativeInteractionClient - handleRedirectPromise called but there is no cached request, returning null."
330
+ );
331
+ return null;
332
+ }
333
+
334
+ const { prompt, ...request } = cachedRequest;
335
+ if (prompt) {
336
+ this.logger.verbose(
337
+ "NativeInteractionClient - handleRedirectPromise called and prompt was included in the original request, removing prompt from cached request to prevent second interaction with native broker window."
338
+ );
339
+ }
340
+
341
+ this.browserStorage.removeItem(
342
+ this.browserStorage.generateCacheKey(
343
+ TemporaryCacheKeys.NATIVE_REQUEST
344
+ )
345
+ );
346
+
347
+ const messageBody: NativeExtensionRequestBody = {
348
+ method: NativeExtensionMethod.GetToken,
349
+ request: request,
350
+ };
351
+
352
+ const reqTimestamp = TimeUtils.nowSeconds();
353
+
354
+ try {
355
+ this.logger.verbose(
356
+ "NativeInteractionClient - handleRedirectPromise sending message to native broker."
357
+ );
358
+ const response: object =
359
+ await this.nativeMessageHandler.sendMessage(messageBody);
360
+ this.validateNativeResponse(response);
361
+ const result = this.handleNativeResponse(
362
+ response as NativeResponse,
363
+ request,
364
+ reqTimestamp
365
+ );
366
+ this.browserStorage.setInteractionInProgress(false);
367
+ return result;
368
+ } catch (e) {
369
+ this.browserStorage.setInteractionInProgress(false);
370
+ throw e;
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Logout from native platform via browser extension
376
+ * @param request
377
+ */
378
+ logout(): Promise<void> {
379
+ this.logger.trace("NativeInteractionClient - logout called.");
380
+ return Promise.reject("Logout not implemented yet");
381
+ }
382
+
383
+ /**
384
+ * Transform response from native platform into AuthenticationResult object which will be returned to the end user
385
+ * @param response
386
+ * @param request
387
+ * @param reqTimestamp
388
+ */
389
+ protected async handleNativeResponse(
390
+ response: NativeResponse,
391
+ request: NativeTokenRequest,
392
+ reqTimestamp: number
393
+ ): Promise<AuthenticationResult> {
394
+ this.logger.trace(
395
+ "NativeInteractionClient - handleNativeResponse called."
396
+ );
397
+
398
+ if (response.account.id !== request.accountId) {
399
+ // User switch in native broker prompt is not supported. All users must first sign in through web flow to ensure server state is in sync
400
+ throw createNativeAuthError(NativeAuthErrorCodes.userSwitch);
401
+ }
402
+
403
+ // Get the preferred_cache domain for the given authority
404
+ const authority = await this.getDiscoveredAuthority(request.authority);
405
+
406
+ // generate identifiers
407
+ const idTokenClaims = AuthToken.extractTokenClaims(
408
+ response.id_token,
409
+ base64Decode
410
+ );
411
+ const homeAccountIdentifier = this.createHomeAccountIdentifier(
412
+ response,
413
+ idTokenClaims
414
+ );
415
+ const accountEntity = AccountEntity.createAccount(
416
+ {
417
+ homeAccountId: homeAccountIdentifier,
418
+ idTokenClaims: idTokenClaims,
419
+ clientInfo: response.client_info,
420
+ nativeAccountId: response.account.id,
421
+ },
422
+ authority
423
+ );
424
+
425
+ // generate authenticationResult
426
+ const result = await this.generateAuthenticationResult(
427
+ response,
428
+ request,
429
+ idTokenClaims,
430
+ accountEntity,
431
+ authority.canonicalAuthority,
432
+ reqTimestamp
433
+ );
434
+
435
+ // cache accounts and tokens in the appropriate storage
436
+ this.cacheAccount(accountEntity);
437
+ this.cacheNativeTokens(
438
+ response,
439
+ request,
440
+ homeAccountIdentifier,
441
+ idTokenClaims,
442
+ result.accessToken,
443
+ result.tenantId,
444
+ reqTimestamp
445
+ );
446
+
447
+ return result;
448
+ }
449
+
450
+ /**
451
+ * creates an homeAccountIdentifier for the account
452
+ * @param response
453
+ * @param idTokenObj
454
+ * @returns
455
+ */
456
+ protected createHomeAccountIdentifier(
457
+ response: NativeResponse,
458
+ idTokenClaims: TokenClaims
459
+ ): string {
460
+ // Save account in browser storage
461
+ const homeAccountIdentifier = AccountEntity.generateHomeAccountId(
462
+ response.client_info || Constants.EMPTY_STRING,
463
+ AuthorityType.Default,
464
+ this.logger,
465
+ this.browserCrypto,
466
+ idTokenClaims
467
+ );
468
+
469
+ return homeAccountIdentifier;
470
+ }
471
+
472
+ /**
473
+ * Helper to generate scopes
474
+ * @param response
475
+ * @param request
476
+ * @returns
477
+ */
478
+ generateScopes(
479
+ response: NativeResponse,
480
+ request: NativeTokenRequest
481
+ ): ScopeSet {
482
+ return response.scope
483
+ ? ScopeSet.fromString(response.scope)
484
+ : ScopeSet.fromString(request.scope);
485
+ }
486
+
487
+ /**
488
+ * If PoP token is requesred, records the PoP token if returned from the WAM, else generates one in the browser
489
+ * @param request
490
+ * @param response
491
+ */
492
+ async generatePopAccessToken(
493
+ response: NativeResponse,
494
+ request: NativeTokenRequest
495
+ ): Promise<string> {
496
+ if (request.tokenType === AuthenticationScheme.POP) {
497
+ /**
498
+ * This code prioritizes SHR returned from the native layer. In case of error/SHR not calculated from WAM and the AT
499
+ * is still received, SHR is calculated locally
500
+ */
501
+
502
+ // Check if native layer returned an SHR token
503
+ if (response.shr) {
504
+ this.logger.trace(
505
+ "handleNativeServerResponse: SHR is enabled in native layer"
506
+ );
507
+ return response.shr;
508
+ }
509
+
510
+ // Generate SHR in msal js if WAM does not compute it when POP is enabled
511
+ const popTokenGenerator: PopTokenGenerator = new PopTokenGenerator(
512
+ this.browserCrypto
513
+ );
514
+ const shrParameters: SignedHttpRequestParameters = {
515
+ resourceRequestMethod: request.resourceRequestMethod,
516
+ resourceRequestUri: request.resourceRequestUri,
517
+ shrClaims: request.shrClaims,
518
+ shrNonce: request.shrNonce,
519
+ };
520
+
521
+ /**
522
+ * KeyID must be present in the native request from when the PoP key was generated in order for
523
+ * PopTokenGenerator to query the full key for signing
524
+ */
525
+ if (!request.keyId) {
526
+ throw createClientAuthError(ClientAuthErrorCodes.keyIdMissing);
527
+ }
528
+ return await popTokenGenerator.signPopToken(
529
+ response.access_token,
530
+ request.keyId,
531
+ shrParameters
532
+ );
533
+ } else {
534
+ return response.access_token;
535
+ }
536
+ }
537
+
538
+ /**
539
+ * Generates authentication result
540
+ * @param response
541
+ * @param request
542
+ * @param idTokenObj
543
+ * @param accountEntity
544
+ * @param authority
545
+ * @param reqTimestamp
546
+ * @returns
547
+ */
548
+ protected async generateAuthenticationResult(
549
+ response: NativeResponse,
550
+ request: NativeTokenRequest,
551
+ idTokenClaims: TokenClaims,
552
+ accountEntity: AccountEntity,
553
+ authority: string,
554
+ reqTimestamp: number
555
+ ): Promise<AuthenticationResult> {
556
+ // Add Native Broker fields to Telemetry
557
+ const mats = this.addTelemetryFromNativeResponse(response);
558
+
559
+ // If scopes not returned in server response, use request scopes
560
+ const responseScopes = response.scope
561
+ ? ScopeSet.fromString(response.scope)
562
+ : ScopeSet.fromString(request.scope);
563
+
564
+ const accountProperties = response.account.properties || {};
565
+ const uid =
566
+ accountProperties["UID"] ||
567
+ idTokenClaims.oid ||
568
+ idTokenClaims.sub ||
569
+ Constants.EMPTY_STRING;
570
+ const tid =
571
+ accountProperties["TenantId"] ||
572
+ idTokenClaims.tid ||
573
+ Constants.EMPTY_STRING;
574
+
575
+ // generate PoP token as needed
576
+ const responseAccessToken = await this.generatePopAccessToken(
577
+ response,
578
+ request
579
+ );
580
+ const tokenType =
581
+ request.tokenType === AuthenticationScheme.POP
582
+ ? AuthenticationScheme.POP
583
+ : AuthenticationScheme.BEARER;
584
+
585
+ const result: AuthenticationResult = {
586
+ authority: authority,
587
+ uniqueId: uid,
588
+ tenantId: tid,
589
+ scopes: responseScopes.asArray(),
590
+ account: accountEntity.getAccountInfo(),
591
+ idToken: response.id_token,
592
+ idTokenClaims: idTokenClaims,
593
+ accessToken: responseAccessToken,
594
+ fromCache: mats ? this.isResponseFromCache(mats) : false,
595
+ expiresOn: new Date(
596
+ Number(reqTimestamp + response.expires_in) * 1000
597
+ ),
598
+ tokenType: tokenType,
599
+ correlationId: this.correlationId,
600
+ state: response.state,
601
+ fromNativeBroker: true,
602
+ };
603
+
604
+ return result;
605
+ }
606
+
607
+ /**
608
+ * cache the account entity in browser storage
609
+ * @param accountEntity
610
+ */
611
+ cacheAccount(accountEntity: AccountEntity): void {
612
+ // Store the account info and hence `nativeAccountId` in browser cache
613
+ this.browserStorage.setAccount(accountEntity);
614
+
615
+ // Remove any existing cached tokens for this account in browser storage
616
+ this.browserStorage.removeAccountContext(accountEntity).catch((e) => {
617
+ this.logger.error(
618
+ `Error occurred while removing account context from browser storage. ${e}`
619
+ );
620
+ });
621
+ }
622
+
623
+ /**
624
+ * Stores the access_token and id_token in inmemory storage
625
+ * @param response
626
+ * @param request
627
+ * @param homeAccountIdentifier
628
+ * @param idTokenObj
629
+ * @param responseAccessToken
630
+ * @param tenantId
631
+ * @param reqTimestamp
632
+ */
633
+ cacheNativeTokens(
634
+ response: NativeResponse,
635
+ request: NativeTokenRequest,
636
+ homeAccountIdentifier: string,
637
+ idTokenClaims: TokenClaims,
638
+ responseAccessToken: string,
639
+ tenantId: string,
640
+ reqTimestamp: number
641
+ ): void {
642
+ const cachedIdToken: IdTokenEntity | null =
643
+ IdTokenEntity.createIdTokenEntity(
644
+ homeAccountIdentifier,
645
+ request.authority,
646
+ response.id_token || "",
647
+ request.clientId,
648
+ idTokenClaims.tid || ""
649
+ );
650
+
651
+ // cache accessToken in inmemory storage
652
+ const expiresIn: number =
653
+ request.tokenType === AuthenticationScheme.POP
654
+ ? Constants.SHR_NONCE_VALIDITY
655
+ : (typeof response.expires_in === "string"
656
+ ? parseInt(response.expires_in, 10)
657
+ : response.expires_in) || 0;
658
+ const tokenExpirationSeconds = reqTimestamp + expiresIn;
659
+ const responseScopes = this.generateScopes(response, request);
660
+
661
+ const cachedAccessToken: AccessTokenEntity | null =
662
+ AccessTokenEntity.createAccessTokenEntity(
663
+ homeAccountIdentifier,
664
+ request.authority,
665
+ responseAccessToken,
666
+ request.clientId,
667
+ idTokenClaims.tid || tenantId,
668
+ responseScopes.printScopes(),
669
+ tokenExpirationSeconds,
670
+ 0,
671
+ this.browserCrypto
672
+ );
673
+
674
+ const nativeCacheRecord = new CacheRecord(
675
+ undefined,
676
+ cachedIdToken,
677
+ cachedAccessToken
678
+ );
679
+
680
+ void this.nativeStorageManager.saveCacheRecord(
681
+ nativeCacheRecord,
682
+ request.storeInCache
683
+ );
684
+ }
685
+
686
+ protected addTelemetryFromNativeResponse(
687
+ response: NativeResponse
688
+ ): MATS | null {
689
+ const mats = this.getMATSFromResponse(response);
690
+
691
+ if (!mats) {
692
+ return null;
693
+ }
694
+
695
+ this.performanceClient.addFields(
696
+ {
697
+ extensionId: this.nativeMessageHandler.getExtensionId(),
698
+ extensionVersion:
699
+ this.nativeMessageHandler.getExtensionVersion(),
700
+ matsBrokerVersion: mats.broker_version,
701
+ matsAccountJoinOnStart: mats.account_join_on_start,
702
+ matsAccountJoinOnEnd: mats.account_join_on_end,
703
+ matsDeviceJoin: mats.device_join,
704
+ matsPromptBehavior: mats.prompt_behavior,
705
+ matsApiErrorCode: mats.api_error_code,
706
+ matsUiVisible: mats.ui_visible,
707
+ matsSilentCode: mats.silent_code,
708
+ matsSilentBiSubCode: mats.silent_bi_sub_code,
709
+ matsSilentMessage: mats.silent_message,
710
+ matsSilentStatus: mats.silent_status,
711
+ matsHttpStatus: mats.http_status,
712
+ matsHttpEventCount: mats.http_event_count,
713
+ },
714
+ this.correlationId
715
+ );
716
+
717
+ return mats;
718
+ }
719
+
720
+ /**
721
+ * Validates native platform response before processing
722
+ * @param response
723
+ */
724
+ private validateNativeResponse(response: object): NativeResponse {
725
+ if (
726
+ response.hasOwnProperty("access_token") &&
727
+ response.hasOwnProperty("id_token") &&
728
+ response.hasOwnProperty("client_info") &&
729
+ response.hasOwnProperty("account") &&
730
+ response.hasOwnProperty("scope") &&
731
+ response.hasOwnProperty("expires_in")
732
+ ) {
733
+ return response as NativeResponse;
734
+ } else {
735
+ throw createAuthError(
736
+ AuthErrorCodes.unexpectedError,
737
+ "Response missing expected properties."
738
+ );
739
+ }
740
+ }
741
+
742
+ /**
743
+ * Gets MATS telemetry from native response
744
+ * @param response
745
+ * @returns
746
+ */
747
+ private getMATSFromResponse(response: NativeResponse): MATS | null {
748
+ if (response.properties.MATS) {
749
+ try {
750
+ return JSON.parse(response.properties.MATS);
751
+ } catch (e) {
752
+ this.logger.error(
753
+ "NativeInteractionClient - Error parsing MATS telemetry, returning null instead"
754
+ );
755
+ }
756
+ }
757
+
758
+ return null;
759
+ }
760
+
761
+ /**
762
+ * Returns whether or not response came from native cache
763
+ * @param response
764
+ * @returns
765
+ */
766
+ protected isResponseFromCache(mats: MATS): boolean {
767
+ if (typeof mats.is_cached === "undefined") {
768
+ this.logger.verbose(
769
+ "NativeInteractionClient - MATS telemetry does not contain field indicating if response was served from cache. Returning false."
770
+ );
771
+ return false;
772
+ }
773
+
774
+ return !!mats.is_cached;
775
+ }
776
+
777
+ /**
778
+ * Translates developer provided request object into NativeRequest object
779
+ * @param request
780
+ */
781
+ protected async initializeNativeRequest(
782
+ request: PopupRequest | SsoSilentRequest
783
+ ): Promise<NativeTokenRequest> {
784
+ this.logger.trace(
785
+ "NativeInteractionClient - initializeNativeRequest called"
786
+ );
787
+
788
+ const authority = request.authority || this.config.auth.authority;
789
+
790
+ if (request.account) {
791
+ await this.validateRequestAuthority(authority, request.account);
792
+ }
793
+
794
+ const canonicalAuthority = new UrlString(authority);
795
+ canonicalAuthority.validateAsUri();
796
+
797
+ // scopes are expected to be received by the native broker as "scope" and will be added to the request below. Other properties that should be dropped from the request to the native broker can be included in the object destructuring here.
798
+ const { scopes, ...remainingProperties } = request;
799
+ const scopeSet = new ScopeSet(scopes || []);
800
+ scopeSet.appendScopes(OIDC_DEFAULT_SCOPES);
801
+
802
+ const getPrompt = () => {
803
+ // If request is silent, prompt is always none
804
+ switch (this.apiId) {
805
+ case ApiId.ssoSilent:
806
+ case ApiId.acquireTokenSilent_silentFlow:
807
+ this.logger.trace(
808
+ "initializeNativeRequest: silent request sets prompt to none"
809
+ );
810
+ return PromptValue.NONE;
811
+ default:
812
+ break;
813
+ }
814
+
815
+ // Prompt not provided, request may proceed and native broker decides if it needs to prompt
816
+ if (!request.prompt) {
817
+ this.logger.trace(
818
+ "initializeNativeRequest: prompt was not provided"
819
+ );
820
+ return undefined;
821
+ }
822
+
823
+ // If request is interactive, check if prompt provided is allowed to go directly to native broker
824
+ switch (request.prompt) {
825
+ case PromptValue.NONE:
826
+ case PromptValue.CONSENT:
827
+ case PromptValue.LOGIN:
828
+ this.logger.trace(
829
+ "initializeNativeRequest: prompt is compatible with native flow"
830
+ );
831
+ return request.prompt;
832
+ default:
833
+ this.logger.trace(
834
+ `initializeNativeRequest: prompt = ${request.prompt} is not compatible with native flow`
835
+ );
836
+ throw createBrowserAuthError(
837
+ BrowserAuthErrorCodes.nativePromptNotSupported
838
+ );
839
+ }
840
+ };
841
+
842
+ const validatedRequest: NativeTokenRequest = {
843
+ ...remainingProperties,
844
+ accountId: this.accountId,
845
+ clientId: this.config.auth.clientId,
846
+ authority: canonicalAuthority.urlString,
847
+ scope: scopeSet.printScopes(),
848
+ redirectUri: this.getRedirectUri(request.redirectUri),
849
+ prompt: getPrompt(),
850
+ correlationId: this.correlationId,
851
+ tokenType: request.authenticationScheme,
852
+ windowTitleSubstring: document.title,
853
+ extraParameters: {
854
+ ...request.extraQueryParameters,
855
+ ...request.tokenQueryParameters,
856
+ },
857
+ extendedExpiryToken: false, // Make this configurable?
858
+ };
859
+
860
+ this.handleExtraBrokerParams(validatedRequest);
861
+ validatedRequest.extraParameters =
862
+ validatedRequest.extraParameters || {};
863
+ validatedRequest.extraParameters.telemetry =
864
+ NativeConstants.MATS_TELEMETRY;
865
+
866
+ if (request.authenticationScheme === AuthenticationScheme.POP) {
867
+ // add POP request type
868
+ const shrParameters: SignedHttpRequestParameters = {
869
+ resourceRequestUri: request.resourceRequestUri,
870
+ resourceRequestMethod: request.resourceRequestMethod,
871
+ shrClaims: request.shrClaims,
872
+ shrNonce: request.shrNonce,
873
+ };
874
+
875
+ const popTokenGenerator = new PopTokenGenerator(this.browserCrypto);
876
+ const reqCnfData = await invokeAsync(
877
+ popTokenGenerator.generateCnf.bind(popTokenGenerator),
878
+ PerformanceEvents.PopTokenGenerateCnf,
879
+ this.logger,
880
+ this.performanceClient,
881
+ this.correlationId
882
+ )(shrParameters, this.logger);
883
+
884
+ // to reduce the URL length, it is recommended to send the hash of the req_cnf instead of the whole string
885
+ validatedRequest.reqCnf = reqCnfData.reqCnfHash;
886
+ validatedRequest.keyId = reqCnfData.kid;
887
+ }
888
+
889
+ return validatedRequest;
890
+ }
891
+
892
+ /**
893
+ * Handles extra broker request parameters
894
+ * @param request {NativeTokenRequest}
895
+ * @private
896
+ */
897
+ private handleExtraBrokerParams(request: NativeTokenRequest): void {
898
+ if (!request.extraParameters) {
899
+ return;
900
+ }
901
+
902
+ if (
903
+ request.extraParameters.hasOwnProperty(
904
+ BrokerServerParamKeys.BROKER_CLIENT_ID
905
+ ) &&
906
+ request.extraParameters.hasOwnProperty(
907
+ BrokerServerParamKeys.BROKER_REDIRECT_URI
908
+ ) &&
909
+ request.extraParameters.hasOwnProperty(AADServerParamKeys.CLIENT_ID)
910
+ ) {
911
+ const child_client_id =
912
+ request.extraParameters[AADServerParamKeys.CLIENT_ID];
913
+ const child_redirect_uri = request.redirectUri;
914
+ const brk_redirect_uri =
915
+ request.extraParameters[
916
+ BrokerServerParamKeys.BROKER_REDIRECT_URI
917
+ ];
918
+ request.extraParameters = {
919
+ child_client_id,
920
+ child_redirect_uri,
921
+ };
922
+ request.redirectUri = brk_redirect_uri;
923
+ }
924
+ }
925
+ }