@azure/msal-browser 3.16.0 → 3.18.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 (102) hide show
  1. package/dist/app/IPublicClientApplication.mjs +1 -1
  2. package/dist/app/PublicClientApplication.mjs +1 -1
  3. package/dist/app/PublicClientNext.mjs +1 -1
  4. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
  5. package/dist/broker/nativeBroker/NativeRequest.d.ts +1 -0
  6. package/dist/broker/nativeBroker/NativeRequest.d.ts.map +1 -1
  7. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  8. package/dist/cache/AccountManager.mjs +1 -1
  9. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  10. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  11. package/dist/cache/BrowserCacheManager.mjs +6 -3
  12. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  13. package/dist/cache/BrowserStorage.mjs +1 -1
  14. package/dist/cache/DatabaseStorage.mjs +1 -1
  15. package/dist/cache/MemoryStorage.mjs +1 -1
  16. package/dist/cache/TokenCache.d.ts.map +1 -1
  17. package/dist/cache/TokenCache.mjs +90 -117
  18. package/dist/cache/TokenCache.mjs.map +1 -1
  19. package/dist/config/Configuration.mjs +1 -1
  20. package/dist/controllers/ControllerFactory.mjs +1 -1
  21. package/dist/controllers/NestedAppAuthController.mjs +1 -1
  22. package/dist/controllers/StandardController.d.ts.map +1 -1
  23. package/dist/controllers/StandardController.mjs +4 -3
  24. package/dist/controllers/StandardController.mjs.map +1 -1
  25. package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
  26. package/dist/crypto/BrowserCrypto.mjs +1 -1
  27. package/dist/crypto/CryptoOps.d.ts +11 -0
  28. package/dist/crypto/CryptoOps.d.ts.map +1 -1
  29. package/dist/crypto/CryptoOps.mjs +16 -1
  30. package/dist/crypto/CryptoOps.mjs.map +1 -1
  31. package/dist/crypto/PkceGenerator.mjs +1 -1
  32. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  33. package/dist/encode/Base64Decode.mjs +1 -1
  34. package/dist/encode/Base64Encode.mjs +1 -1
  35. package/dist/error/BrowserAuthError.d.ts +5 -0
  36. package/dist/error/BrowserAuthError.d.ts.map +1 -1
  37. package/dist/error/BrowserAuthError.mjs +7 -2
  38. package/dist/error/BrowserAuthError.mjs.map +1 -1
  39. package/dist/error/BrowserAuthErrorCodes.d.ts +1 -0
  40. package/dist/error/BrowserAuthErrorCodes.d.ts.map +1 -1
  41. package/dist/error/BrowserAuthErrorCodes.mjs +3 -2
  42. package/dist/error/BrowserAuthErrorCodes.mjs.map +1 -1
  43. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  44. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  45. package/dist/error/NativeAuthError.mjs +1 -1
  46. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  47. package/dist/error/NestedAppAuthError.mjs +2 -2
  48. package/dist/error/NestedAppAuthError.mjs.map +1 -1
  49. package/dist/event/EventHandler.mjs +1 -1
  50. package/dist/event/EventMessage.mjs +1 -1
  51. package/dist/event/EventType.mjs +1 -1
  52. package/dist/index.mjs +1 -1
  53. package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
  54. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  55. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  56. package/dist/interaction_client/NativeInteractionClient.mjs +36 -15
  57. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  58. package/dist/interaction_client/PopupClient.mjs +1 -1
  59. package/dist/interaction_client/RedirectClient.mjs +1 -1
  60. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  61. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  62. package/dist/interaction_client/SilentIframeClient.mjs +1 -1
  63. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  64. package/dist/interaction_client/StandardInteractionClient.mjs +1 -1
  65. package/dist/interaction_handler/InteractionHandler.mjs +1 -1
  66. package/dist/interaction_handler/RedirectHandler.mjs +1 -1
  67. package/dist/interaction_handler/SilentHandler.mjs +1 -1
  68. package/dist/naa/BridgeError.mjs +1 -1
  69. package/dist/naa/BridgeProxy.mjs +1 -1
  70. package/dist/naa/BridgeStatusCode.mjs +1 -1
  71. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +1 -1
  72. package/dist/navigation/NavigationClient.mjs +1 -1
  73. package/dist/network/FetchClient.mjs +1 -1
  74. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  75. package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
  76. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  77. package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
  78. package/dist/packageMetadata.d.ts +1 -1
  79. package/dist/packageMetadata.mjs +2 -2
  80. package/dist/request/RequestHelpers.mjs +1 -1
  81. package/dist/response/ResponseHandler.mjs +1 -1
  82. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  83. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  84. package/dist/utils/BrowserConstants.mjs +1 -1
  85. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  86. package/dist/utils/BrowserUtils.mjs +1 -1
  87. package/lib/msal-browser.cjs +283 -254
  88. package/lib/msal-browser.cjs.map +1 -1
  89. package/lib/msal-browser.js +283 -254
  90. package/lib/msal-browser.js.map +1 -1
  91. package/lib/msal-browser.min.js +63 -64
  92. package/package.json +3 -2
  93. package/src/broker/nativeBroker/NativeRequest.ts +1 -0
  94. package/src/cache/BrowserCacheManager.ts +4 -5
  95. package/src/cache/TokenCache.ts +158 -243
  96. package/src/controllers/StandardController.ts +6 -5
  97. package/src/crypto/CryptoOps.ts +17 -0
  98. package/src/error/BrowserAuthError.ts +8 -0
  99. package/src/error/BrowserAuthErrorCodes.ts +1 -0
  100. package/src/error/NestedAppAuthError.ts +1 -1
  101. package/src/interaction_client/NativeInteractionClient.ts +52 -23
  102. package/src/packageMetadata.ts +1 -1
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "type": "git",
11
11
  "url": "https://github.com/AzureAD/microsoft-authentication-library-for-js.git"
12
12
  },
13
- "version": "3.16.0",
13
+ "version": "3.18.0",
14
14
  "description": "Microsoft Authentication Library for js",
15
15
  "keywords": [
16
16
  "implicit",
@@ -23,6 +23,7 @@
23
23
  ],
24
24
  "type": "module",
25
25
  "sideEffects": false,
26
+ "main": "./lib/msal-browser.cjs",
26
27
  "module": "./dist/index.mjs",
27
28
  "types": "./dist/index.d.ts",
28
29
  "exports": {
@@ -103,6 +104,6 @@
103
104
  "typescript": "^4.9.5"
104
105
  },
105
106
  "dependencies": {
106
- "@azure/msal-common": "14.11.0"
107
+ "@azure/msal-common": "14.13.0"
107
108
  }
108
109
  }
@@ -31,6 +31,7 @@ export type NativeTokenRequest = {
31
31
  extendedExpiryToken?: boolean;
32
32
  extraParameters?: StringDict;
33
33
  storeInCache?: StoreInCache; // Object of booleans indicating whether to store tokens in the cache or not (default is true)
34
+ signPopToken?: boolean; // Set to true only if token request deos not contain a PoP keyId
34
35
  };
35
36
 
36
37
  /**
@@ -1864,11 +1864,10 @@ export class BrowserCacheManager extends CacheManager {
1864
1864
  claimsHash
1865
1865
  );
1866
1866
 
1867
- const cacheRecord = new CacheRecord(
1868
- undefined,
1869
- idTokenEntity,
1870
- accessTokenEntity
1871
- );
1867
+ const cacheRecord = {
1868
+ idToken: idTokenEntity,
1869
+ accessToken: accessTokenEntity,
1870
+ };
1872
1871
  return this.saveCacheRecord(cacheRecord);
1873
1872
  }
1874
1873
 
@@ -15,7 +15,6 @@ import {
15
15
  AccountEntity,
16
16
  AuthToken,
17
17
  RefreshTokenEntity,
18
- Constants,
19
18
  CacheRecord,
20
19
  TokenClaims,
21
20
  CacheHelpers,
@@ -81,149 +80,76 @@ export class TokenCache implements ITokenCache {
81
80
  response: ExternalTokenResponse,
82
81
  options: LoadTokenOptions
83
82
  ): AuthenticationResult {
84
- this.logger.info("TokenCache - loadExternalTokens called");
85
-
86
- if (!response.id_token) {
83
+ if (!this.isBrowserEnvironment) {
87
84
  throw createBrowserAuthError(
88
- BrowserAuthErrorCodes.unableToLoadToken
85
+ BrowserAuthErrorCodes.nonBrowserEnvironment
89
86
  );
90
87
  }
91
88
 
92
- const idTokenClaims = AuthToken.extractTokenClaims(
93
- response.id_token,
94
- base64Decode
89
+ const idTokenClaims = response.id_token
90
+ ? AuthToken.extractTokenClaims(response.id_token, base64Decode)
91
+ : undefined;
92
+
93
+ const authorityOptions: AuthorityOptions = {
94
+ protocolMode: this.config.auth.protocolMode,
95
+ knownAuthorities: this.config.auth.knownAuthorities,
96
+ cloudDiscoveryMetadata: this.config.auth.cloudDiscoveryMetadata,
97
+ authorityMetadata: this.config.auth.authorityMetadata,
98
+ skipAuthorityMetadataCache:
99
+ this.config.auth.skipAuthorityMetadataCache,
100
+ };
101
+ const authority = request.authority
102
+ ? new Authority(
103
+ Authority.generateAuthority(
104
+ request.authority,
105
+ request.azureCloudOptions
106
+ ),
107
+ this.config.system.networkClient,
108
+ this.storage,
109
+ authorityOptions,
110
+ this.logger,
111
+ request.correlationId || BrowserCrypto.createNewGuid()
112
+ )
113
+ : undefined;
114
+
115
+ const cacheRecordAccount: AccountEntity = this.loadAccount(
116
+ request,
117
+ options.clientInfo || response.client_info || "",
118
+ idTokenClaims,
119
+ authority
95
120
  );
96
121
 
97
- let cacheRecord: CacheRecord;
98
- let authority: Authority | undefined;
99
- let cacheRecordAccount: AccountEntity;
122
+ const idToken = this.loadIdToken(
123
+ response,
124
+ cacheRecordAccount.homeAccountId,
125
+ cacheRecordAccount.environment,
126
+ cacheRecordAccount.realm
127
+ );
100
128
 
101
- if (request.account) {
102
- cacheRecordAccount = AccountEntity.createFromAccountInfo(
103
- request.account
104
- );
105
- cacheRecord = new CacheRecord(
106
- cacheRecordAccount,
107
- this.loadIdToken(
108
- response.id_token,
109
- cacheRecordAccount.homeAccountId,
110
- request.account.environment,
111
- request.account.tenantId
112
- ),
113
- this.loadAccessToken(
114
- request,
115
- response,
116
- cacheRecordAccount.homeAccountId,
117
- request.account.environment,
118
- request.account.tenantId,
119
- options
120
- ),
121
- this.loadRefreshToken(
122
- request,
123
- response,
124
- cacheRecordAccount.homeAccountId,
125
- request.account.environment
126
- )
127
- );
128
- } else if (request.authority) {
129
- const authorityUrl = Authority.generateAuthority(
130
- request.authority,
131
- request.azureCloudOptions
132
- );
133
- const authorityOptions: AuthorityOptions = {
134
- protocolMode: this.config.auth.protocolMode,
135
- knownAuthorities: this.config.auth.knownAuthorities,
136
- cloudDiscoveryMetadata: this.config.auth.cloudDiscoveryMetadata,
137
- authorityMetadata: this.config.auth.authorityMetadata,
138
- skipAuthorityMetadataCache:
139
- this.config.auth.skipAuthorityMetadataCache,
140
- };
141
- authority = new Authority(
142
- authorityUrl,
143
- this.config.system.networkClient,
144
- this.storage,
145
- authorityOptions,
146
- this.logger,
147
- request.correlationId || BrowserCrypto.createNewGuid()
148
- );
129
+ const accessToken = this.loadAccessToken(
130
+ request,
131
+ response,
132
+ cacheRecordAccount.homeAccountId,
133
+ cacheRecordAccount.environment,
134
+ cacheRecordAccount.realm,
135
+ options
136
+ );
149
137
 
150
- // "clientInfo" from options takes precedence over "clientInfo" in response
151
- if (options.clientInfo) {
152
- this.logger.trace("TokenCache - homeAccountId from options");
153
- cacheRecordAccount = this.loadAccount(
154
- idTokenClaims,
155
- authority,
156
- options.clientInfo
157
- );
158
- cacheRecord = new CacheRecord(
159
- cacheRecordAccount,
160
- this.loadIdToken(
161
- response.id_token,
162
- cacheRecordAccount.homeAccountId,
163
- authority.hostnameAndPort,
164
- authority.tenant
165
- ),
166
- this.loadAccessToken(
167
- request,
168
- response,
169
- cacheRecordAccount.homeAccountId,
170
- authority.hostnameAndPort,
171
- authority.tenant,
172
- options
173
- ),
174
- this.loadRefreshToken(
175
- request,
176
- response,
177
- cacheRecordAccount.homeAccountId,
178
- authority.hostnameAndPort
179
- )
180
- );
181
- } else if (response.client_info) {
182
- this.logger.trace("TokenCache - homeAccountId from response");
183
- cacheRecordAccount = this.loadAccount(
184
- idTokenClaims,
185
- authority,
186
- response.client_info
187
- );
188
- cacheRecord = new CacheRecord(
189
- cacheRecordAccount,
190
- this.loadIdToken(
191
- response.id_token,
192
- cacheRecordAccount.homeAccountId,
193
- authority.hostnameAndPort,
194
- authority.tenant
195
- ),
196
- this.loadAccessToken(
197
- request,
198
- response,
199
- cacheRecordAccount.homeAccountId,
200
- authority.hostnameAndPort,
201
- authority.tenant,
202
- options
203
- ),
204
- this.loadRefreshToken(
205
- request,
206
- response,
207
- cacheRecordAccount.homeAccountId,
208
- authority.hostnameAndPort
209
- )
210
- );
211
- } else {
212
- throw createBrowserAuthError(
213
- BrowserAuthErrorCodes.unableToLoadToken
214
- );
215
- }
216
- } else {
217
- throw createBrowserAuthError(
218
- BrowserAuthErrorCodes.unableToLoadToken
219
- );
220
- }
138
+ const refreshToken = this.loadRefreshToken(
139
+ response,
140
+ cacheRecordAccount.homeAccountId,
141
+ cacheRecordAccount.environment
142
+ );
221
143
 
222
144
  return this.generateAuthenticationResult(
223
145
  request,
146
+ {
147
+ account: cacheRecordAccount,
148
+ idToken,
149
+ accessToken,
150
+ refreshToken,
151
+ },
224
152
  idTokenClaims,
225
- cacheRecord,
226
- cacheRecordAccount,
227
153
  authority
228
154
  );
229
155
  }
@@ -238,54 +164,54 @@ export class TokenCache implements ITokenCache {
238
164
  * @returns `AccountEntity`
239
165
  */
240
166
  private loadAccount(
241
- idTokenClaims: TokenClaims,
242
- authority: Authority,
243
- clientInfo?: string,
244
- requestHomeAccountId?: string
167
+ request: SilentRequest,
168
+ clientInfo: string,
169
+ idTokenClaims?: TokenClaims,
170
+ authority?: Authority
245
171
  ): AccountEntity {
246
- if (this.isBrowserEnvironment) {
247
- this.logger.verbose("TokenCache - loading account");
248
- let homeAccountId;
249
- if (requestHomeAccountId) {
250
- homeAccountId = requestHomeAccountId;
251
- } else if (authority.authorityType !== undefined && clientInfo) {
252
- homeAccountId = AccountEntity.generateHomeAccountId(
253
- clientInfo,
254
- authority.authorityType,
255
- this.logger,
256
- this.cryptoObj,
257
- idTokenClaims
258
- );
259
- }
260
-
261
- if (!homeAccountId) {
262
- throw createBrowserAuthError(
263
- BrowserAuthErrorCodes.unableToLoadToken
264
- );
265
- }
266
- const claimsTenantId = idTokenClaims.tid;
267
-
268
- const cachedAccount = buildAccountToCache(
269
- this.storage,
270
- authority,
271
- homeAccountId,
272
- idTokenClaims,
273
- base64Decode,
274
- clientInfo,
275
- authority.hostnameAndPort,
276
- claimsTenantId,
277
- undefined, // authCodePayload
278
- undefined, // nativeAccountId
279
- this.logger
280
- );
172
+ this.logger.verbose("TokenCache - loading account");
281
173
 
282
- this.storage.setAccount(cachedAccount);
283
- return cachedAccount;
284
- } else {
174
+ if (request.account) {
175
+ const accountEntity = AccountEntity.createFromAccountInfo(
176
+ request.account
177
+ );
178
+ this.storage.setAccount(accountEntity);
179
+ return accountEntity;
180
+ } else if (!authority || (!clientInfo && !idTokenClaims)) {
181
+ this.logger.error(
182
+ "TokenCache - if an account is not provided on the request, authority and either clientInfo or idToken must be provided instead."
183
+ );
285
184
  throw createBrowserAuthError(
286
185
  BrowserAuthErrorCodes.unableToLoadToken
287
186
  );
288
187
  }
188
+
189
+ const homeAccountId = AccountEntity.generateHomeAccountId(
190
+ clientInfo,
191
+ authority.authorityType,
192
+ this.logger,
193
+ this.cryptoObj,
194
+ idTokenClaims
195
+ );
196
+
197
+ const claimsTenantId = idTokenClaims?.tid;
198
+
199
+ const cachedAccount = buildAccountToCache(
200
+ this.storage,
201
+ authority,
202
+ homeAccountId,
203
+ base64Decode,
204
+ idTokenClaims,
205
+ clientInfo,
206
+ authority.hostnameAndPort,
207
+ claimsTenantId,
208
+ undefined, // authCodePayload
209
+ undefined, // nativeAccountId
210
+ this.logger
211
+ );
212
+
213
+ this.storage.setAccount(cachedAccount);
214
+ return cachedAccount;
289
215
  }
290
216
 
291
217
  /**
@@ -297,28 +223,27 @@ export class TokenCache implements ITokenCache {
297
223
  * @returns `IdTokenEntity`
298
224
  */
299
225
  private loadIdToken(
300
- idToken: string,
226
+ response: ExternalTokenResponse,
301
227
  homeAccountId: string,
302
228
  environment: string,
303
229
  tenantId: string
304
- ): IdTokenEntity {
230
+ ): IdTokenEntity | null {
231
+ if (!response.id_token) {
232
+ this.logger.verbose("TokenCache - no id token found in response");
233
+ return null;
234
+ }
235
+
236
+ this.logger.verbose("TokenCache - loading id token");
305
237
  const idTokenEntity = CacheHelpers.createIdTokenEntity(
306
238
  homeAccountId,
307
239
  environment,
308
- idToken,
240
+ response.id_token,
309
241
  this.config.auth.clientId,
310
242
  tenantId
311
243
  );
312
244
 
313
- if (this.isBrowserEnvironment) {
314
- this.logger.verbose("TokenCache - loading id token");
315
- this.storage.setIdTokenCredential(idTokenEntity);
316
- return idTokenEntity;
317
- } else {
318
- throw createBrowserAuthError(
319
- BrowserAuthErrorCodes.unableToLoadToken
320
- );
321
- }
245
+ this.storage.setIdTokenCredential(idTokenEntity);
246
+ return idTokenEntity;
322
247
  }
323
248
 
324
249
  /**
@@ -340,28 +265,37 @@ export class TokenCache implements ITokenCache {
340
265
  ): AccessTokenEntity | null {
341
266
  if (!response.access_token) {
342
267
  this.logger.verbose(
343
- "TokenCache - No access token provided for caching"
268
+ "TokenCache - no access token found in response"
344
269
  );
345
270
  return null;
346
- }
347
-
348
- if (!response.expires_in) {
349
- throw createBrowserAuthError(
350
- BrowserAuthErrorCodes.unableToLoadToken
271
+ } else if (!response.expires_in) {
272
+ this.logger.error(
273
+ "TokenCache - no expiration set on the access token. Cannot add it to the cache."
351
274
  );
352
- }
353
-
354
- if (!options.extendedExpiresOn) {
355
- throw createBrowserAuthError(
356
- BrowserAuthErrorCodes.unableToLoadToken
275
+ return null;
276
+ } else if (
277
+ !response.scope &&
278
+ (!request.scopes || !request.scopes.length)
279
+ ) {
280
+ this.logger.error(
281
+ "TokenCache - scopes not specified in the request or response. Cannot add token to the cache."
357
282
  );
283
+ return null;
358
284
  }
359
285
 
360
- const scopes = new ScopeSet(request.scopes).printScopes();
286
+ this.logger.verbose("TokenCache - loading access token");
287
+
288
+ const scopes = response.scope
289
+ ? ScopeSet.fromString(response.scope)
290
+ : new ScopeSet(request.scopes);
361
291
  const expiresOn =
362
292
  options.expiresOn ||
363
293
  response.expires_in + new Date().getTime() / 1000;
364
- const extendedExpiresOn = options.extendedExpiresOn;
294
+
295
+ const extendedExpiresOn =
296
+ options.extendedExpiresOn ||
297
+ (response.ext_expires_in || response.expires_in) +
298
+ new Date().getTime() / 1000;
365
299
 
366
300
  const accessTokenEntity = CacheHelpers.createAccessTokenEntity(
367
301
  homeAccountId,
@@ -369,21 +303,14 @@ export class TokenCache implements ITokenCache {
369
303
  response.access_token,
370
304
  this.config.auth.clientId,
371
305
  tenantId,
372
- scopes,
306
+ scopes.printScopes(),
373
307
  expiresOn,
374
308
  extendedExpiresOn,
375
309
  base64Decode
376
310
  );
377
311
 
378
- if (this.isBrowserEnvironment) {
379
- this.logger.verbose("TokenCache - loading access token");
380
- this.storage.setAccessTokenCredential(accessTokenEntity);
381
- return accessTokenEntity;
382
- } else {
383
- throw createBrowserAuthError(
384
- BrowserAuthErrorCodes.unableToLoadToken
385
- );
386
- }
312
+ this.storage.setAccessTokenCredential(accessTokenEntity);
313
+ return accessTokenEntity;
387
314
  }
388
315
 
389
316
  /**
@@ -395,34 +322,30 @@ export class TokenCache implements ITokenCache {
395
322
  * @returns `RefreshTokenEntity`
396
323
  */
397
324
  private loadRefreshToken(
398
- request: SilentRequest,
399
325
  response: ExternalTokenResponse,
400
326
  homeAccountId: string,
401
327
  environment: string
402
328
  ): RefreshTokenEntity | null {
403
329
  if (!response.refresh_token) {
404
330
  this.logger.verbose(
405
- "TokenCache - No refresh token provided for caching"
331
+ "TokenCache - no refresh token found in response"
406
332
  );
407
333
  return null;
408
334
  }
409
335
 
336
+ this.logger.verbose("TokenCache - loading refresh token");
410
337
  const refreshTokenEntity = CacheHelpers.createRefreshTokenEntity(
411
338
  homeAccountId,
412
339
  environment,
413
340
  response.refresh_token,
414
- this.config.auth.clientId
341
+ this.config.auth.clientId,
342
+ response.foci,
343
+ undefined, // userAssertionHash
344
+ response.refresh_token_expires_in
415
345
  );
416
346
 
417
- if (this.isBrowserEnvironment) {
418
- this.logger.verbose("TokenCache - loading refresh token");
419
- this.storage.setRefreshTokenCredential(refreshTokenEntity);
420
- return refreshTokenEntity;
421
- } else {
422
- throw createBrowserAuthError(
423
- BrowserAuthErrorCodes.unableToLoadToken
424
- );
425
- }
347
+ this.storage.setRefreshTokenCredential(refreshTokenEntity);
348
+ return refreshTokenEntity;
426
349
  }
427
350
 
428
351
  /**
@@ -435,12 +358,11 @@ export class TokenCache implements ITokenCache {
435
358
  */
436
359
  private generateAuthenticationResult(
437
360
  request: SilentRequest,
438
- idTokenClaims: TokenClaims,
439
- cacheRecord: CacheRecord,
440
- accountEntity: AccountEntity,
361
+ cacheRecord: CacheRecord & { account: AccountEntity },
362
+ idTokenClaims?: TokenClaims,
441
363
  authority?: Authority
442
364
  ): AuthenticationResult {
443
- let accessToken: string = Constants.EMPTY_STRING;
365
+ let accessToken: string = "";
444
366
  let responseScopes: Array<string> = [];
445
367
  let expiresOn: Date | null = null;
446
368
  let extExpiresOn: Date | undefined;
@@ -458,16 +380,12 @@ export class TokenCache implements ITokenCache {
458
380
  );
459
381
  }
460
382
 
461
- const uid =
462
- idTokenClaims.oid || idTokenClaims.sub || Constants.EMPTY_STRING;
463
- const tid = idTokenClaims.tid || Constants.EMPTY_STRING;
383
+ const accountEntity = cacheRecord.account;
464
384
 
465
385
  return {
466
- authority: authority
467
- ? authority.canonicalAuthority
468
- : Constants.EMPTY_STRING,
469
- uniqueId: uid,
470
- tenantId: tid,
386
+ authority: authority ? authority.canonicalAuthority : "",
387
+ uniqueId: cacheRecord.account.localAccountId,
388
+ tenantId: cacheRecord.account.realm,
471
389
  scopes: responseScopes,
472
390
  account: accountEntity.getAccountInfo(),
473
391
  idToken: cacheRecord.idToken?.secret || "",
@@ -475,17 +393,14 @@ export class TokenCache implements ITokenCache {
475
393
  accessToken: accessToken,
476
394
  fromCache: true,
477
395
  expiresOn: expiresOn,
478
- correlationId: request.correlationId || Constants.EMPTY_STRING,
479
- requestId: Constants.EMPTY_STRING,
396
+ correlationId: request.correlationId || "",
397
+ requestId: "",
480
398
  extExpiresOn: extExpiresOn,
481
- familyId: Constants.EMPTY_STRING,
482
- tokenType:
483
- cacheRecord?.accessToken?.tokenType || Constants.EMPTY_STRING,
484
- state: Constants.EMPTY_STRING,
485
- cloudGraphHostName:
486
- accountEntity.cloudGraphHostName || Constants.EMPTY_STRING,
487
- msGraphHost: accountEntity.msGraphHost || Constants.EMPTY_STRING,
488
- code: undefined,
399
+ familyId: cacheRecord.refreshToken?.familyId || "",
400
+ tokenType: cacheRecord?.accessToken?.tokenType || "",
401
+ state: request.state || "",
402
+ cloudGraphHostName: accountEntity.cloudGraphHostName || "",
403
+ msGraphHost: accountEntity.msGraphHost || "",
489
404
  fromNativeBroker: false,
490
405
  };
491
406
  }
@@ -1963,6 +1963,8 @@ export class StandardController implements IController {
1963
1963
  request: SilentRequest & { correlationId: string },
1964
1964
  account: AccountInfo
1965
1965
  ): Promise<AuthenticationResult> {
1966
+ const trackPageVisibility = () =>
1967
+ this.trackPageVisibility(request.correlationId);
1966
1968
  this.performanceClient.addQueueMeasurement(
1967
1969
  PerformanceEvents.AcquireTokenSilentAsync,
1968
1970
  request.correlationId
@@ -1981,9 +1983,7 @@ export class StandardController implements IController {
1981
1983
  );
1982
1984
  }
1983
1985
 
1984
- document.addEventListener("visibilitychange", () =>
1985
- this.trackPageVisibility(request.correlationId)
1986
- );
1986
+ document.addEventListener("visibilitychange", trackPageVisibility);
1987
1987
 
1988
1988
  const silentRequest = await invokeAsync(
1989
1989
  initializeSilentRequest,
@@ -2124,8 +2124,9 @@ export class StandardController implements IController {
2124
2124
  throw tokenRenewalError;
2125
2125
  })
2126
2126
  .finally(() => {
2127
- document.removeEventListener("visibilitychange", () =>
2128
- this.trackPageVisibility(request.correlationId)
2127
+ document.removeEventListener(
2128
+ "visibilitychange",
2129
+ trackPageVisibility
2129
2130
  );
2130
2131
  });
2131
2132
  }
@@ -78,6 +78,23 @@ export class CryptoOps implements ICrypto {
78
78
  return base64Decode(input);
79
79
  }
80
80
 
81
+ /**
82
+ * Encodes input string to base64 URL safe string.
83
+ * @param input
84
+ */
85
+ base64UrlEncode(input: string): string {
86
+ return urlEncode(input);
87
+ }
88
+
89
+ /**
90
+ * Stringifies and base64Url encodes input public key
91
+ * @param inputKid
92
+ * @returns Base64Url encoded public key
93
+ */
94
+ encodeKid(inputKid: string): string {
95
+ return this.base64UrlEncode(JSON.stringify({ kid: inputKid }));
96
+ }
97
+
81
98
  /**
82
99
  * Generates a keypair, stores it and returns a thumbprint
83
100
  * @param request
@@ -90,6 +90,8 @@ export const BrowserAuthErrorMessages = {
90
90
  "The provided prompt is not supported by the native platform. This request should be routed to the web based flow.",
91
91
  [BrowserAuthErrorCodes.invalidBase64String]:
92
92
  "Invalid base64 encoded string.",
93
+ [BrowserAuthErrorCodes.invalidPopTokenRequest]:
94
+ "Invalid PoP token request. The request should not have both a popKid value and signPopToken set to true.",
93
95
  };
94
96
 
95
97
  /**
@@ -333,6 +335,12 @@ export const BrowserAuthErrorMessage = {
333
335
  BrowserAuthErrorCodes.invalidBase64String
334
336
  ],
335
337
  },
338
+ invalidPopTokenRequest: {
339
+ code: BrowserAuthErrorCodes.invalidPopTokenRequest,
340
+ desc: BrowserAuthErrorMessages[
341
+ BrowserAuthErrorCodes.invalidPopTokenRequest
342
+ ],
343
+ },
336
344
  };
337
345
 
338
346
  /**
@@ -55,3 +55,4 @@ export const uninitializedPublicClientApplication =
55
55
  "uninitialized_public_client_application";
56
56
  export const nativePromptNotSupported = "native_prompt_not_supported";
57
57
  export const invalidBase64String = "invalid_base64_string";
58
+ export const invalidPopTokenRequest = "invalid_pop_token_request";
@@ -11,7 +11,7 @@ import { AuthError } from "@azure/msal-common";
11
11
  export const NestedAppAuthErrorMessage = {
12
12
  unsupportedMethod: {
13
13
  code: "unsupported_method",
14
- desc: "The PKCE code challenge and verifier could not be generated.",
14
+ desc: "This method is not supported in nested app environment.",
15
15
  },
16
16
  };
17
17