@azure/msal-browser 3.17.0 → 3.19.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 (110) hide show
  1. package/dist/app/IPublicClientApplication.d.ts +2 -1
  2. package/dist/app/IPublicClientApplication.d.ts.map +1 -1
  3. package/dist/app/IPublicClientApplication.mjs +1 -1
  4. package/dist/app/IPublicClientApplication.mjs.map +1 -1
  5. package/dist/app/PublicClientApplication.d.ts +8 -1
  6. package/dist/app/PublicClientApplication.d.ts.map +1 -1
  7. package/dist/app/PublicClientApplication.mjs +9 -4
  8. package/dist/app/PublicClientApplication.mjs.map +1 -1
  9. package/dist/app/PublicClientNext.mjs +1 -1
  10. package/dist/broker/nativeBroker/NativeMessageHandler.mjs +1 -1
  11. package/dist/broker/nativeBroker/NativeStatusCodes.mjs +1 -1
  12. package/dist/cache/AccountManager.mjs +1 -1
  13. package/dist/cache/AsyncMemoryStorage.mjs +1 -1
  14. package/dist/cache/BrowserCacheManager.d.ts +2 -1
  15. package/dist/cache/BrowserCacheManager.d.ts.map +1 -1
  16. package/dist/cache/BrowserCacheManager.mjs +9 -5
  17. package/dist/cache/BrowserCacheManager.mjs.map +1 -1
  18. package/dist/cache/BrowserStorage.mjs +1 -1
  19. package/dist/cache/DatabaseStorage.mjs +1 -1
  20. package/dist/cache/MemoryStorage.mjs +1 -1
  21. package/dist/cache/TokenCache.d.ts.map +1 -1
  22. package/dist/cache/TokenCache.mjs +90 -117
  23. package/dist/cache/TokenCache.mjs.map +1 -1
  24. package/dist/config/Configuration.mjs +1 -1
  25. package/dist/controllers/ControllerFactory.d.ts +2 -1
  26. package/dist/controllers/ControllerFactory.d.ts.map +1 -1
  27. package/dist/controllers/ControllerFactory.mjs +3 -3
  28. package/dist/controllers/ControllerFactory.mjs.map +1 -1
  29. package/dist/controllers/IController.d.ts +2 -1
  30. package/dist/controllers/IController.d.ts.map +1 -1
  31. package/dist/controllers/NestedAppAuthController.mjs +1 -1
  32. package/dist/controllers/StandardController.d.ts +4 -2
  33. package/dist/controllers/StandardController.d.ts.map +1 -1
  34. package/dist/controllers/StandardController.mjs +11 -8
  35. package/dist/controllers/StandardController.mjs.map +1 -1
  36. package/dist/controllers/UnknownOperatingContextController.mjs +1 -1
  37. package/dist/crypto/BrowserCrypto.mjs +1 -1
  38. package/dist/crypto/CryptoOps.mjs +1 -1
  39. package/dist/crypto/PkceGenerator.mjs +1 -1
  40. package/dist/crypto/SignedHttpRequest.mjs +1 -1
  41. package/dist/encode/Base64Decode.mjs +1 -1
  42. package/dist/encode/Base64Encode.mjs +1 -1
  43. package/dist/error/BrowserAuthError.mjs +1 -1
  44. package/dist/error/BrowserAuthErrorCodes.mjs +1 -1
  45. package/dist/error/BrowserConfigurationAuthError.mjs +1 -1
  46. package/dist/error/BrowserConfigurationAuthErrorCodes.mjs +1 -1
  47. package/dist/error/NativeAuthError.mjs +1 -1
  48. package/dist/error/NativeAuthErrorCodes.mjs +1 -1
  49. package/dist/error/NestedAppAuthError.mjs +2 -2
  50. package/dist/error/NestedAppAuthError.mjs.map +1 -1
  51. package/dist/event/EventHandler.mjs +1 -1
  52. package/dist/event/EventMessage.mjs +1 -1
  53. package/dist/event/EventType.mjs +1 -1
  54. package/dist/index.d.ts +1 -0
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.mjs +1 -1
  57. package/dist/interaction_client/BaseInteractionClient.mjs +1 -1
  58. package/dist/interaction_client/HybridSpaAuthorizationCodeClient.mjs +1 -1
  59. package/dist/interaction_client/NativeInteractionClient.d.ts.map +1 -1
  60. package/dist/interaction_client/NativeInteractionClient.mjs +11 -7
  61. package/dist/interaction_client/NativeInteractionClient.mjs.map +1 -1
  62. package/dist/interaction_client/PopupClient.mjs +1 -1
  63. package/dist/interaction_client/RedirectClient.mjs +1 -1
  64. package/dist/interaction_client/SilentAuthCodeClient.mjs +1 -1
  65. package/dist/interaction_client/SilentCacheClient.mjs +1 -1
  66. package/dist/interaction_client/SilentIframeClient.mjs +1 -1
  67. package/dist/interaction_client/SilentRefreshClient.mjs +1 -1
  68. package/dist/interaction_client/StandardInteractionClient.mjs +1 -1
  69. package/dist/interaction_handler/InteractionHandler.mjs +1 -1
  70. package/dist/interaction_handler/RedirectHandler.mjs +1 -1
  71. package/dist/interaction_handler/SilentHandler.mjs +1 -1
  72. package/dist/naa/BridgeError.mjs +1 -1
  73. package/dist/naa/BridgeProxy.mjs +1 -1
  74. package/dist/naa/BridgeStatusCode.mjs +1 -1
  75. package/dist/naa/mapping/NestedAppAuthAdapter.mjs +1 -1
  76. package/dist/navigation/NavigationClient.mjs +1 -1
  77. package/dist/network/FetchClient.mjs +1 -1
  78. package/dist/operatingcontext/BaseOperatingContext.mjs +1 -1
  79. package/dist/operatingcontext/NestedAppOperatingContext.mjs +1 -1
  80. package/dist/operatingcontext/StandardOperatingContext.mjs +1 -1
  81. package/dist/operatingcontext/UnknownOperatingContext.mjs +1 -1
  82. package/dist/packageMetadata.d.ts +1 -1
  83. package/dist/packageMetadata.mjs +2 -2
  84. package/dist/request/InitializeApplicationRequest.d.ts +9 -0
  85. package/dist/request/InitializeApplicationRequest.d.ts.map +1 -0
  86. package/dist/request/RequestHelpers.mjs +1 -1
  87. package/dist/response/ResponseHandler.mjs +1 -1
  88. package/dist/telemetry/BrowserPerformanceClient.mjs +1 -1
  89. package/dist/telemetry/BrowserPerformanceMeasurement.mjs +1 -1
  90. package/dist/utils/BrowserConstants.mjs +1 -1
  91. package/dist/utils/BrowserProtocolUtils.mjs +1 -1
  92. package/dist/utils/BrowserUtils.mjs +1 -1
  93. package/lib/msal-browser.cjs +214 -248
  94. package/lib/msal-browser.cjs.map +1 -1
  95. package/lib/msal-browser.js +214 -248
  96. package/lib/msal-browser.js.map +1 -1
  97. package/lib/msal-browser.min.js +63 -64
  98. package/package.json +3 -2
  99. package/src/app/IPublicClientApplication.ts +3 -1
  100. package/src/app/PublicClientApplication.ts +9 -3
  101. package/src/cache/BrowserCacheManager.ts +9 -7
  102. package/src/cache/TokenCache.ts +158 -243
  103. package/src/controllers/ControllerFactory.ts +4 -2
  104. package/src/controllers/IController.ts +3 -1
  105. package/src/controllers/StandardController.ts +19 -11
  106. package/src/error/NestedAppAuthError.ts +1 -1
  107. package/src/index.ts +1 -0
  108. package/src/interaction_client/NativeInteractionClient.ts +12 -10
  109. package/src/packageMetadata.ts +1 -1
  110. package/src/request/InitializeApplicationRequest.ts +13 -0
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.17.0",
13
+ "version": "3.19.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.12.0"
107
+ "@azure/msal-common": "14.13.0"
107
108
  }
108
109
  }
@@ -27,9 +27,11 @@ import { BrowserConfiguration } from "../config/Configuration";
27
27
  import { AuthenticationResult } from "../response/AuthenticationResult";
28
28
  import { EventCallbackFunction } from "../event/EventMessage";
29
29
  import { ClearCacheRequest } from "../request/ClearCacheRequest";
30
+ import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest";
30
31
 
31
32
  export interface IPublicClientApplication {
32
- initialize(): Promise<void>;
33
+ // TODO: Make request mandatory in the next major version?
34
+ initialize(request?: InitializeApplicationRequest): Promise<void>;
33
35
  acquireTokenPopup(request: PopupRequest): Promise<AuthenticationResult>;
34
36
  acquireTokenRedirect(request: RedirectRequest): Promise<void>;
35
37
  acquireTokenSilent(
@@ -30,6 +30,7 @@ import { ClearCacheRequest } from "../request/ClearCacheRequest";
30
30
  import { EndSessionPopupRequest } from "../request/EndSessionPopupRequest";
31
31
  import { NestedAppAuthController } from "../controllers/NestedAppAuthController";
32
32
  import { NestedAppOperatingContext } from "../operatingcontext/NestedAppOperatingContext";
33
+ import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest";
33
34
 
34
35
  /**
35
36
  * The PublicClientApplication class is the object exposed by the library to perform authentication and authorization functions in Single Page Applications
@@ -38,7 +39,11 @@ import { NestedAppOperatingContext } from "../operatingcontext/NestedAppOperatin
38
39
  export class PublicClientApplication implements IPublicClientApplication {
39
40
  protected controller: IController;
40
41
 
41
- // creates StandardController and passes it to the PublicClientApplication
42
+ /**
43
+ * Creates StandardController and passes it to the PublicClientApplication
44
+ *
45
+ * @param configuration {Configuration}
46
+ */
42
47
  public static async createPublicClientApplication(
43
48
  configuration: Configuration
44
49
  ): Promise<IPublicClientApplication> {
@@ -80,9 +85,10 @@ export class PublicClientApplication implements IPublicClientApplication {
80
85
 
81
86
  /**
82
87
  * Initializer function to perform async startup tasks such as connecting to WAM extension
88
+ * @param request {?InitializeApplicationRequest}
83
89
  */
84
- async initialize(): Promise<void> {
85
- return this.controller.initialize();
90
+ async initialize(request?: InitializeApplicationRequest): Promise<void> {
91
+ return this.controller.initialize(request);
86
92
  }
87
93
 
88
94
  /**
@@ -1266,13 +1266,16 @@ export class BrowserCacheManager extends CacheManager {
1266
1266
  /**
1267
1267
  * Clears all access tokes that have claims prior to saving the current one
1268
1268
  * @param performanceClient {IPerformanceClient}
1269
+ * @param correlationId {string} correlation id
1269
1270
  * @returns
1270
1271
  */
1271
1272
  async clearTokensAndKeysWithClaims(
1272
- performanceClient: IPerformanceClient
1273
+ performanceClient: IPerformanceClient,
1274
+ correlationId: string
1273
1275
  ): Promise<void> {
1274
1276
  performanceClient.addQueueMeasurement(
1275
- PerformanceEvents.ClearTokensAndKeysWithClaims
1277
+ PerformanceEvents.ClearTokensAndKeysWithClaims,
1278
+ correlationId
1276
1279
  );
1277
1280
 
1278
1281
  const tokenKeys = this.getTokenKeys();
@@ -1864,11 +1867,10 @@ export class BrowserCacheManager extends CacheManager {
1864
1867
  claimsHash
1865
1868
  );
1866
1869
 
1867
- const cacheRecord = new CacheRecord(
1868
- undefined,
1869
- idTokenEntity,
1870
- accessTokenEntity
1871
- );
1870
+ const cacheRecord = {
1871
+ idToken: idTokenEntity,
1872
+ accessToken: accessTokenEntity,
1873
+ };
1872
1874
  return this.saveCacheRecord(cacheRecord);
1873
1875
  }
1874
1876
 
@@ -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
  }
@@ -9,14 +9,16 @@ import { IController } from "./IController";
9
9
  import { Configuration } from "../config/Configuration";
10
10
  import { StandardController } from "./StandardController";
11
11
  import { NestedAppAuthController } from "./NestedAppAuthController";
12
+ import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest";
12
13
 
13
14
  export async function createV3Controller(
14
- config: Configuration
15
+ config: Configuration,
16
+ request?: InitializeApplicationRequest
15
17
  ): Promise<IController> {
16
18
  const standard = new StandardOperatingContext(config);
17
19
 
18
20
  await standard.initialize();
19
- return StandardController.createController(standard);
21
+ return StandardController.createController(standard, request);
20
22
  }
21
23
 
22
24
  export async function createController(
@@ -25,9 +25,11 @@ import { EventHandler } from "../event/EventHandler";
25
25
  import { AuthenticationResult } from "../response/AuthenticationResult";
26
26
  import { EventCallbackFunction } from "../event/EventMessage";
27
27
  import { ClearCacheRequest } from "../request/ClearCacheRequest";
28
+ import { InitializeApplicationRequest } from "../request/InitializeApplicationRequest";
28
29
 
29
30
  export interface IController {
30
- initialize(): Promise<void>;
31
+ // TODO: Make request mandatory in the next major version?
32
+ initialize(request?: InitializeApplicationRequest): Promise<void>;
31
33
 
32
34
  acquireTokenPopup(request: PopupRequest): Promise<AuthenticationResult>;
33
35