@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,151 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { BrowserStringUtils } from "../utils/BrowserStringUtils";
7
+ import {
8
+ createBrowserAuthError,
9
+ BrowserAuthErrorCodes,
10
+ } from "../error/BrowserAuthError";
11
+ import {
12
+ IPerformanceClient,
13
+ Logger,
14
+ PerformanceEvents,
15
+ } from "@azure/msal-common";
16
+ import { KEY_FORMAT_JWK } from "../utils/BrowserConstants";
17
+
18
+ /**
19
+ * This file defines functions used by the browser library to perform cryptography operations such as
20
+ * hashing and encoding. It also has helper functions to validate the availability of specific APIs.
21
+ */
22
+
23
+ /**
24
+ * See here for more info on RsaHashedKeyGenParams: https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
25
+ */
26
+ // RSA KeyGen Algorithm
27
+ const PKCS1_V15_KEYGEN_ALG = "RSASSA-PKCS1-v1_5";
28
+ // SHA-256 hashing algorithm
29
+ const S256_HASH_ALG = "SHA-256";
30
+ // MOD length for PoP tokens
31
+ const MODULUS_LENGTH = 2048;
32
+ // Public Exponent
33
+ const PUBLIC_EXPONENT: Uint8Array = new Uint8Array([0x01, 0x00, 0x01]);
34
+
35
+ const keygenAlgorithmOptions: RsaHashedKeyGenParams = {
36
+ name: PKCS1_V15_KEYGEN_ALG,
37
+ hash: S256_HASH_ALG,
38
+ modulusLength: MODULUS_LENGTH,
39
+ publicExponent: PUBLIC_EXPONENT,
40
+ };
41
+
42
+ /**
43
+ * Check whether browser crypto is available.
44
+ */
45
+ export function validateCryptoAvailable(logger: Logger): void {
46
+ if ("crypto" in window) {
47
+ logger.verbose("BrowserCrypto: modern crypto interface available");
48
+ } else {
49
+ logger.error("BrowserCrypto: crypto interface is unavailable");
50
+ throw createBrowserAuthError(BrowserAuthErrorCodes.cryptoNonExistent);
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Returns a sha-256 hash of the given dataString as an ArrayBuffer.
56
+ * @param dataString
57
+ */
58
+ export async function sha256Digest(
59
+ dataString: string,
60
+ performanceClient?: IPerformanceClient,
61
+ correlationId?: string
62
+ ): Promise<ArrayBuffer> {
63
+ performanceClient?.addQueueMeasurement(
64
+ PerformanceEvents.Sha256Digest,
65
+ correlationId
66
+ );
67
+ const data = BrowserStringUtils.stringToUtf8Arr(dataString);
68
+ return window.crypto.subtle.digest(
69
+ S256_HASH_ALG,
70
+ data
71
+ ) as Promise<ArrayBuffer>;
72
+ }
73
+
74
+ /**
75
+ * Populates buffer with cryptographically random values.
76
+ * @param dataBuffer
77
+ */
78
+ export function getRandomValues(dataBuffer: Uint8Array): Uint8Array {
79
+ return window.crypto.getRandomValues(dataBuffer);
80
+ }
81
+
82
+ /**
83
+ * Creates a new random GUID
84
+ * @returns
85
+ */
86
+ export function createNewGuid(): string {
87
+ return window.crypto.randomUUID();
88
+ }
89
+
90
+ /**
91
+ * Generates a keypair based on current keygen algorithm config.
92
+ * @param extractable
93
+ * @param usages
94
+ */
95
+ export async function generateKeyPair(
96
+ extractable: boolean,
97
+ usages: Array<KeyUsage>
98
+ ): Promise<CryptoKeyPair> {
99
+ return window.crypto.subtle.generateKey(
100
+ keygenAlgorithmOptions,
101
+ extractable,
102
+ usages
103
+ ) as Promise<CryptoKeyPair>;
104
+ }
105
+
106
+ /**
107
+ * Export key as Json Web Key (JWK)
108
+ * @param key
109
+ */
110
+ export async function exportJwk(key: CryptoKey): Promise<JsonWebKey> {
111
+ return window.crypto.subtle.exportKey(
112
+ KEY_FORMAT_JWK,
113
+ key
114
+ ) as Promise<JsonWebKey>;
115
+ }
116
+
117
+ /**
118
+ * Imports key as Json Web Key (JWK), can set extractable and usages.
119
+ * @param key
120
+ * @param extractable
121
+ * @param usages
122
+ */
123
+ export async function importJwk(
124
+ key: JsonWebKey,
125
+ extractable: boolean,
126
+ usages: Array<KeyUsage>
127
+ ): Promise<CryptoKey> {
128
+ return window.crypto.subtle.importKey(
129
+ KEY_FORMAT_JWK,
130
+ key,
131
+ keygenAlgorithmOptions,
132
+ extractable,
133
+ usages
134
+ ) as Promise<CryptoKey>;
135
+ }
136
+
137
+ /**
138
+ * Signs given data with given key
139
+ * @param key
140
+ * @param data
141
+ */
142
+ export async function sign(
143
+ key: CryptoKey,
144
+ data: ArrayBuffer
145
+ ): Promise<ArrayBuffer> {
146
+ return window.crypto.subtle.sign(
147
+ keygenAlgorithmOptions,
148
+ key,
149
+ data
150
+ ) as Promise<ArrayBuffer>;
151
+ }
@@ -0,0 +1,235 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ ICrypto,
8
+ IPerformanceClient,
9
+ JoseHeader,
10
+ Logger,
11
+ PerformanceEvents,
12
+ SignedHttpRequest,
13
+ SignedHttpRequestParameters,
14
+ } from "@azure/msal-common";
15
+ import { base64Encode, urlEncode, urlEncodeArr } from "../encode/Base64Encode";
16
+ import { base64Decode } from "../encode/Base64Decode";
17
+ import * as BrowserCrypto from "./BrowserCrypto";
18
+ import { BrowserStringUtils } from "../utils/BrowserStringUtils";
19
+ import {
20
+ createBrowserAuthError,
21
+ BrowserAuthErrorCodes,
22
+ } from "../error/BrowserAuthError";
23
+ import { CryptoKeyStore } from "../cache/CryptoKeyStore";
24
+
25
+ export type CachedKeyPair = {
26
+ publicKey: CryptoKey;
27
+ privateKey: CryptoKey;
28
+ requestMethod?: string;
29
+ requestUri?: string;
30
+ };
31
+
32
+ /**
33
+ * This class implements MSAL's crypto interface, which allows it to perform base64 encoding and decoding, generating cryptographically random GUIDs and
34
+ * implementing Proof Key for Code Exchange specs for the OAuth Authorization Code Flow using PKCE (rfc here: https://tools.ietf.org/html/rfc7636).
35
+ */
36
+ export class CryptoOps implements ICrypto {
37
+ private logger: Logger;
38
+
39
+ /**
40
+ * CryptoOps can be used in contexts outside a PCA instance,
41
+ * meaning there won't be a performance manager available.
42
+ */
43
+ private performanceClient: IPerformanceClient | undefined;
44
+
45
+ private static POP_KEY_USAGES: Array<KeyUsage> = ["sign", "verify"];
46
+ private static EXTRACTABLE: boolean = true;
47
+ private cache: CryptoKeyStore;
48
+
49
+ constructor(logger: Logger, performanceClient?: IPerformanceClient) {
50
+ this.logger = logger;
51
+ // Browser crypto needs to be validated first before any other classes can be set.
52
+ BrowserCrypto.validateCryptoAvailable(logger);
53
+ this.cache = new CryptoKeyStore(this.logger);
54
+ this.performanceClient = performanceClient;
55
+ }
56
+
57
+ /**
58
+ * Creates a new random GUID - used to populate state and nonce.
59
+ * @returns string (GUID)
60
+ */
61
+ createNewGuid(): string {
62
+ return BrowserCrypto.createNewGuid();
63
+ }
64
+
65
+ /**
66
+ * Encodes input string to base64.
67
+ * @param input
68
+ */
69
+ base64Encode(input: string): string {
70
+ return base64Encode(input);
71
+ }
72
+
73
+ /**
74
+ * Decodes input string from base64.
75
+ * @param input
76
+ */
77
+ base64Decode(input: string): string {
78
+ return base64Decode(input);
79
+ }
80
+
81
+ /**
82
+ * Generates a keypair, stores it and returns a thumbprint
83
+ * @param request
84
+ */
85
+ async getPublicKeyThumbprint(
86
+ request: SignedHttpRequestParameters
87
+ ): Promise<string> {
88
+ const publicKeyThumbMeasurement =
89
+ this.performanceClient?.startMeasurement(
90
+ PerformanceEvents.CryptoOptsGetPublicKeyThumbprint,
91
+ request.correlationId
92
+ );
93
+
94
+ // Generate Keypair
95
+ const keyPair: CryptoKeyPair = await BrowserCrypto.generateKeyPair(
96
+ CryptoOps.EXTRACTABLE,
97
+ CryptoOps.POP_KEY_USAGES
98
+ );
99
+
100
+ // Generate Thumbprint for Public Key
101
+ const publicKeyJwk: JsonWebKey = await BrowserCrypto.exportJwk(
102
+ keyPair.publicKey
103
+ );
104
+
105
+ const pubKeyThumprintObj: JsonWebKey = {
106
+ e: publicKeyJwk.e,
107
+ kty: publicKeyJwk.kty,
108
+ n: publicKeyJwk.n,
109
+ };
110
+
111
+ const publicJwkString: string =
112
+ BrowserStringUtils.getSortedObjectString(pubKeyThumprintObj);
113
+ const publicJwkHash = await this.hashString(publicJwkString);
114
+
115
+ // Generate Thumbprint for Private Key
116
+ const privateKeyJwk: JsonWebKey = await BrowserCrypto.exportJwk(
117
+ keyPair.privateKey
118
+ );
119
+ // Re-import private key to make it unextractable
120
+ const unextractablePrivateKey: CryptoKey =
121
+ await BrowserCrypto.importJwk(privateKeyJwk, false, ["sign"]);
122
+
123
+ // Store Keypair data in keystore
124
+ await this.cache.asymmetricKeys.setItem(publicJwkHash, {
125
+ privateKey: unextractablePrivateKey,
126
+ publicKey: keyPair.publicKey,
127
+ requestMethod: request.resourceRequestMethod,
128
+ requestUri: request.resourceRequestUri,
129
+ });
130
+
131
+ if (publicKeyThumbMeasurement) {
132
+ publicKeyThumbMeasurement.end({
133
+ success: true,
134
+ });
135
+ }
136
+
137
+ return publicJwkHash;
138
+ }
139
+
140
+ /**
141
+ * Removes cryptographic keypair from key store matching the keyId passed in
142
+ * @param kid
143
+ */
144
+ async removeTokenBindingKey(kid: string): Promise<boolean> {
145
+ await this.cache.asymmetricKeys.removeItem(kid);
146
+ const keyFound = await this.cache.asymmetricKeys.containsKey(kid);
147
+ return !keyFound;
148
+ }
149
+
150
+ /**
151
+ * Removes all cryptographic keys from IndexedDB storage
152
+ */
153
+ async clearKeystore(): Promise<boolean> {
154
+ return await this.cache.clear();
155
+ }
156
+
157
+ /**
158
+ * Signs the given object as a jwt payload with private key retrieved by given kid.
159
+ * @param payload
160
+ * @param kid
161
+ */
162
+ async signJwt(
163
+ payload: SignedHttpRequest,
164
+ kid: string,
165
+ correlationId?: string
166
+ ): Promise<string> {
167
+ const signJwtMeasurement = this.performanceClient?.startMeasurement(
168
+ PerformanceEvents.CryptoOptsSignJwt,
169
+ correlationId
170
+ );
171
+ const cachedKeyPair = await this.cache.asymmetricKeys.getItem(kid);
172
+
173
+ if (!cachedKeyPair) {
174
+ throw createBrowserAuthError(
175
+ BrowserAuthErrorCodes.cryptoKeyNotFound
176
+ );
177
+ }
178
+
179
+ // Get public key as JWK
180
+ const publicKeyJwk = await BrowserCrypto.exportJwk(
181
+ cachedKeyPair.publicKey
182
+ );
183
+ const publicKeyJwkString =
184
+ BrowserStringUtils.getSortedObjectString(publicKeyJwk);
185
+
186
+ // Base64URL encode public key thumbprint with keyId only: BASE64URL({ kid: "FULL_PUBLIC_KEY_HASH" })
187
+ const encodedKeyIdThumbprint = urlEncode(JSON.stringify({ kid: kid }));
188
+
189
+ // Generate header
190
+ const shrHeader = JoseHeader.getShrHeaderString({
191
+ kid: encodedKeyIdThumbprint,
192
+ alg: publicKeyJwk.alg,
193
+ });
194
+ const encodedShrHeader = urlEncode(shrHeader);
195
+
196
+ // Generate payload
197
+ payload.cnf = {
198
+ jwk: JSON.parse(publicKeyJwkString),
199
+ };
200
+ const encodedPayload = urlEncode(JSON.stringify(payload));
201
+
202
+ // Form token string
203
+ const tokenString = `${encodedShrHeader}.${encodedPayload}`;
204
+
205
+ // Sign token
206
+ const tokenBuffer = BrowserStringUtils.stringToUtf8Arr(tokenString);
207
+ const signatureBuffer = await BrowserCrypto.sign(
208
+ cachedKeyPair.privateKey,
209
+ tokenBuffer
210
+ );
211
+ const encodedSignature = urlEncodeArr(new Uint8Array(signatureBuffer));
212
+
213
+ const signedJwt = `${tokenString}.${encodedSignature}`;
214
+
215
+ if (signJwtMeasurement) {
216
+ signJwtMeasurement.end({
217
+ success: true,
218
+ });
219
+ }
220
+
221
+ return signedJwt;
222
+ }
223
+
224
+ /**
225
+ * Returns the SHA-256 hash of an input string
226
+ * @param plainText
227
+ */
228
+ async hashString(plainText: string): Promise<string> {
229
+ const hashBuffer: ArrayBuffer = await BrowserCrypto.sha256Digest(
230
+ plainText
231
+ );
232
+ const hashBytes = new Uint8Array(hashBuffer);
233
+ return urlEncodeArr(hashBytes);
234
+ }
235
+ }
@@ -0,0 +1,115 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ IPerformanceClient,
8
+ Logger,
9
+ PerformanceEvents,
10
+ PkceCodes,
11
+ invoke,
12
+ invokeAsync,
13
+ } from "@azure/msal-common";
14
+ import {
15
+ createBrowserAuthError,
16
+ BrowserAuthErrorCodes,
17
+ } from "../error/BrowserAuthError";
18
+ import { urlEncodeArr } from "../encode/Base64Encode";
19
+ import { getRandomValues, sha256Digest } from "./BrowserCrypto";
20
+
21
+ // Constant byte array length
22
+ const RANDOM_BYTE_ARR_LENGTH = 32;
23
+
24
+ /**
25
+ * This file defines APIs to generate PKCE codes and code verifiers.
26
+ */
27
+
28
+ /**
29
+ * Generates PKCE Codes. See the RFC for more information: https://tools.ietf.org/html/rfc7636
30
+ */
31
+ export async function generatePkceCodes(
32
+ performanceClient: IPerformanceClient,
33
+ logger: Logger,
34
+ correlationId: string
35
+ ): Promise<PkceCodes> {
36
+ performanceClient.addQueueMeasurement(
37
+ PerformanceEvents.GeneratePkceCodes,
38
+ correlationId
39
+ );
40
+ const codeVerifier = invoke(
41
+ generateCodeVerifier,
42
+ PerformanceEvents.GenerateCodeVerifier,
43
+ logger,
44
+ performanceClient,
45
+ correlationId
46
+ )(performanceClient, logger, correlationId);
47
+ const codeChallenge = await invokeAsync(
48
+ generateCodeChallengeFromVerifier,
49
+ PerformanceEvents.GenerateCodeChallengeFromVerifier,
50
+ logger,
51
+ performanceClient,
52
+ correlationId
53
+ )(codeVerifier, performanceClient, logger, correlationId);
54
+ return {
55
+ verifier: codeVerifier,
56
+ challenge: codeChallenge,
57
+ };
58
+ }
59
+
60
+ /**
61
+ * Generates a random 32 byte buffer and returns the base64
62
+ * encoded string to be used as a PKCE Code Verifier
63
+ */
64
+ function generateCodeVerifier(
65
+ performanceClient: IPerformanceClient,
66
+ logger: Logger,
67
+ correlationId: string
68
+ ): string {
69
+ try {
70
+ // Generate random values as utf-8
71
+ const buffer: Uint8Array = new Uint8Array(RANDOM_BYTE_ARR_LENGTH);
72
+ invoke(
73
+ getRandomValues,
74
+ PerformanceEvents.GetRandomValues,
75
+ logger,
76
+ performanceClient,
77
+ correlationId
78
+ )(buffer);
79
+ // encode verifier as base64
80
+ const pkceCodeVerifierB64: string = urlEncodeArr(buffer);
81
+ return pkceCodeVerifierB64;
82
+ } catch (e) {
83
+ throw createBrowserAuthError(BrowserAuthErrorCodes.pkceNotCreated);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Creates a base64 encoded PKCE Code Challenge string from the
89
+ * hash created from the PKCE Code Verifier supplied
90
+ */
91
+ async function generateCodeChallengeFromVerifier(
92
+ pkceCodeVerifier: string,
93
+ performanceClient: IPerformanceClient,
94
+ logger: Logger,
95
+ correlationId: string
96
+ ): Promise<string> {
97
+ performanceClient.addQueueMeasurement(
98
+ PerformanceEvents.GenerateCodeChallengeFromVerifier,
99
+ correlationId
100
+ );
101
+ try {
102
+ // hashed verifier
103
+ const pkceHashedCodeVerifier = await invokeAsync(
104
+ sha256Digest,
105
+ PerformanceEvents.Sha256Digest,
106
+ logger,
107
+ performanceClient,
108
+ correlationId
109
+ )(pkceCodeVerifier, performanceClient, correlationId);
110
+ // encode hash as base64
111
+ return urlEncodeArr(new Uint8Array(pkceHashedCodeVerifier));
112
+ } catch (e) {
113
+ throw createBrowserAuthError(BrowserAuthErrorCodes.pkceNotCreated);
114
+ }
115
+ }
@@ -0,0 +1,76 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import { CryptoOps } from "./CryptoOps";
7
+ import {
8
+ Logger,
9
+ LoggerOptions,
10
+ PopTokenGenerator,
11
+ SignedHttpRequestParameters,
12
+ } from "@azure/msal-common";
13
+ import { version, name } from "../packageMetadata";
14
+
15
+ export type SignedHttpRequestOptions = {
16
+ loggerOptions: LoggerOptions;
17
+ };
18
+
19
+ export class SignedHttpRequest {
20
+ private popTokenGenerator: PopTokenGenerator;
21
+ private cryptoOps: CryptoOps;
22
+ private shrParameters: SignedHttpRequestParameters;
23
+ private logger: Logger;
24
+
25
+ constructor(
26
+ shrParameters: SignedHttpRequestParameters,
27
+ shrOptions?: SignedHttpRequestOptions
28
+ ) {
29
+ const loggerOptions = (shrOptions && shrOptions.loggerOptions) || {};
30
+ this.logger = new Logger(loggerOptions, name, version);
31
+ this.cryptoOps = new CryptoOps(this.logger);
32
+ this.popTokenGenerator = new PopTokenGenerator(this.cryptoOps);
33
+ this.shrParameters = shrParameters;
34
+ }
35
+
36
+ /**
37
+ * Generates and caches a keypair for the given request options.
38
+ * @returns Public key digest, which should be sent to the token issuer.
39
+ */
40
+ async generatePublicKeyThumbprint(): Promise<string> {
41
+ const { kid } = await this.popTokenGenerator.generateKid(
42
+ this.shrParameters
43
+ );
44
+
45
+ return kid;
46
+ }
47
+
48
+ /**
49
+ * Generates a signed http request for the given payload with the given key.
50
+ * @param payload Payload to sign (e.g. access token)
51
+ * @param publicKeyThumbprint Public key digest (from generatePublicKeyThumbprint API)
52
+ * @param claims Additional claims to include/override in the signed JWT
53
+ * @returns Pop token signed with the corresponding private key
54
+ */
55
+ async signRequest(
56
+ payload: string,
57
+ publicKeyThumbprint: string,
58
+ claims?: object
59
+ ): Promise<string> {
60
+ return this.popTokenGenerator.signPayload(
61
+ payload,
62
+ publicKeyThumbprint,
63
+ this.shrParameters,
64
+ claims
65
+ );
66
+ }
67
+
68
+ /**
69
+ * Removes cached keys from browser for given public key thumbprint
70
+ * @param publicKeyThumbprint Public key digest (from generatePublicKeyThumbprint API)
71
+ * @returns If keys are properly deleted
72
+ */
73
+ async removeKeys(publicKeyThumbprint: string): Promise<boolean> {
74
+ return await this.cryptoOps.removeTokenBindingKey(publicKeyThumbprint);
75
+ }
76
+ }
@@ -0,0 +1,46 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ import {
7
+ BrowserAuthErrorCodes,
8
+ createBrowserAuthError,
9
+ } from "../error/BrowserAuthError";
10
+
11
+ /**
12
+ * Class which exposes APIs to decode base64 strings to plaintext. See here for implementation details:
13
+ * https://developer.mozilla.org/en-US/docs/Glossary/Base64#the_unicode_problem
14
+ */
15
+
16
+ /**
17
+ * Returns a URL-safe plaintext decoded string from b64 encoded input.
18
+ * @param input
19
+ */
20
+ export function base64Decode(input: string): string {
21
+ return new TextDecoder().decode(base64DecToArr(input));
22
+ }
23
+
24
+ /**
25
+ * Decodes base64 into Uint8Array
26
+ * @param base64String
27
+ */
28
+ function base64DecToArr(base64String: string): Uint8Array {
29
+ let encodedString = base64String.replace(/-/g, "+").replace(/_/g, "/");
30
+ switch (encodedString.length % 4) {
31
+ case 0:
32
+ break;
33
+ case 2:
34
+ encodedString += "==";
35
+ break;
36
+ case 3:
37
+ encodedString += "=";
38
+ break;
39
+ default:
40
+ throw createBrowserAuthError(
41
+ BrowserAuthErrorCodes.invalidBase64String
42
+ );
43
+ }
44
+ const binString = atob(encodedString);
45
+ return Uint8Array.from(binString, (m) => m.codePointAt(0) || 0);
46
+ }
@@ -0,0 +1,52 @@
1
+ /*
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * Class which exposes APIs to encode plaintext to base64 encoded string. See here for implementation details:
8
+ * https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#Solution_2_%E2%80%93_JavaScript's_UTF-16_%3E_UTF-8_%3E_base64
9
+ */
10
+
11
+ /**
12
+ * Returns URL Safe b64 encoded string from a plaintext string.
13
+ * @param input
14
+ */
15
+ export function urlEncode(input: string): string {
16
+ return encodeURIComponent(
17
+ base64Encode(input)
18
+ .replace(/=/g, "")
19
+ .replace(/\+/g, "-")
20
+ .replace(/\//g, "_")
21
+ );
22
+ }
23
+
24
+ /**
25
+ * Returns URL Safe b64 encoded string from an int8Array.
26
+ * @param inputArr
27
+ */
28
+ export function urlEncodeArr(inputArr: Uint8Array): string {
29
+ return base64EncArr(inputArr)
30
+ .replace(/=/g, "")
31
+ .replace(/\+/g, "-")
32
+ .replace(/\//g, "_");
33
+ }
34
+
35
+ /**
36
+ * Returns b64 encoded string from plaintext string.
37
+ * @param input
38
+ */
39
+ export function base64Encode(input: string): string {
40
+ return base64EncArr(new TextEncoder().encode(input));
41
+ }
42
+
43
+ /**
44
+ * Base64 encode byte array
45
+ * @param aBytes
46
+ */
47
+ function base64EncArr(aBytes: Uint8Array): string {
48
+ const binString = Array.from(aBytes, (x) => String.fromCodePoint(x)).join(
49
+ ""
50
+ );
51
+ return btoa(binString);
52
+ }