@azure/msal-react 1.1.2 → 1.3.1

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.
@@ -3,4 +3,7 @@ import { IPublicClientApplication } from "@azure/msal-browser";
3
3
  export declare type MsalProviderProps = PropsWithChildren<{
4
4
  instance: IPublicClientApplication;
5
5
  }>;
6
+ /**
7
+ * MSAL context provider component. This must be rendered above any other components that use MSAL.
8
+ */
6
9
  export declare function MsalProvider({ instance, children }: MsalProviderProps): React.ReactElement;
@@ -0,0 +1,16 @@
1
+ import { AuthError } from "@azure/msal-browser";
2
+ export declare const ReactAuthErrorMessage: {
3
+ invalidInteractionType: {
4
+ code: string;
5
+ desc: string;
6
+ };
7
+ unableToFallbackToInteraction: {
8
+ code: string;
9
+ desc: string;
10
+ };
11
+ };
12
+ export declare class ReactAuthError extends AuthError {
13
+ constructor(errorCode: string, errorMessage?: string);
14
+ static createInvalidInteractionTypeError(): ReactAuthError;
15
+ static createUnableToFallbackToInteractionError(): ReactAuthError;
16
+ }
@@ -4,4 +4,4 @@ import { AccountIdentifiers } from "../types/AccountIdentifiers";
4
4
  * Given 1 or more accountIdentifiers, returns the Account object if the user is signed-in
5
5
  * @param accountIdentifiers
6
6
  */
7
- export declare function useAccount(accountIdentifiers: AccountIdentifiers): AccountInfo | null;
7
+ export declare function useAccount(accountIdentifiers?: AccountIdentifiers): AccountInfo | null;
@@ -1,13 +1,15 @@
1
- import { PopupRequest, RedirectRequest, SsoSilentRequest, InteractionType, AuthenticationResult, AuthError } from "@azure/msal-browser";
1
+ import { PopupRequest, RedirectRequest, SsoSilentRequest, InteractionType, AuthenticationResult, AuthError, SilentRequest } from "@azure/msal-browser";
2
2
  import { AccountIdentifiers } from "../types/AccountIdentifiers";
3
3
  export declare type MsalAuthenticationResult = {
4
- login: Function;
4
+ login: (callbackInteractionType?: InteractionType | undefined, callbackRequest?: PopupRequest | RedirectRequest | SilentRequest) => Promise<AuthenticationResult | null>;
5
+ acquireToken: (callbackInteractionType?: InteractionType | undefined, callbackRequest?: SilentRequest | undefined) => Promise<AuthenticationResult | null>;
5
6
  result: AuthenticationResult | null;
6
7
  error: AuthError | null;
7
8
  };
8
9
  /**
9
- * Invokes a login call if a user is not currently signed-in. Failed logins can be retried using the login callback returned.
10
- * Optionally provide a request object to be used in the login call.
10
+ * If a user is not currently signed in this hook invokes a login. Failed logins can be retried using the login callback returned.
11
+ * If a user is currently signed in this hook attempts to acquire a token. Subsequent token requests can use the acquireToken callback returned.
12
+ * Optionally provide a request object to be used in the login/acquireToken call.
11
13
  * Optionally provide a specific user that should be logged in.
12
14
  * @param interactionType
13
15
  * @param authenticationRequest
@@ -60,15 +60,101 @@ function accountArraysAreEqual(arrayA, arrayB) {
60
60
  return elementA.homeAccountId === elementB.homeAccountId && elementA.localAccountId === elementB.localAccountId && elementA.username === elementB.username;
61
61
  });
62
62
  }
63
+ function getAccountByIdentifiers(allAccounts, accountIdentifiers) {
64
+ if (allAccounts.length > 0 && (accountIdentifiers.homeAccountId || accountIdentifiers.localAccountId || accountIdentifiers.username)) {
65
+ const matchedAccounts = allAccounts.filter(accountObj => {
66
+ if (accountIdentifiers.username && accountIdentifiers.username.toLowerCase() !== accountObj.username.toLowerCase()) {
67
+ return false;
68
+ }
69
+
70
+ if (accountIdentifiers.homeAccountId && accountIdentifiers.homeAccountId.toLowerCase() !== accountObj.homeAccountId.toLowerCase()) {
71
+ return false;
72
+ }
73
+
74
+ if (accountIdentifiers.localAccountId && accountIdentifiers.localAccountId.toLowerCase() !== accountObj.localAccountId.toLowerCase()) {
75
+ return false;
76
+ }
77
+
78
+ return true;
79
+ });
80
+ return matchedAccounts[0] || null;
81
+ } else {
82
+ return null;
83
+ }
84
+ }
63
85
 
64
86
  /* eslint-disable header/header */
65
87
  const name = "@azure/msal-react";
66
- const version = "1.1.2";
88
+ const version = "1.3.1";
67
89
 
68
90
  /*
69
91
  * Copyright (c) Microsoft Corporation. All rights reserved.
70
92
  * Licensed under the MIT License.
71
93
  */
94
+ var MsalProviderActionType;
95
+
96
+ (function (MsalProviderActionType) {
97
+ MsalProviderActionType["UNBLOCK_INPROGRESS"] = "UNBLOCK_INPROGRESS";
98
+ MsalProviderActionType["EVENT"] = "EVENT";
99
+ })(MsalProviderActionType || (MsalProviderActionType = {}));
100
+ /**
101
+ * Returns the next inProgress and accounts state based on event message
102
+ * @param previousState
103
+ * @param action
104
+ */
105
+
106
+
107
+ const reducer = (previousState, action) => {
108
+ const {
109
+ type,
110
+ payload
111
+ } = action;
112
+ let newAccounts = previousState.accounts;
113
+ let newInProgress = previousState.inProgress;
114
+
115
+ switch (type) {
116
+ case MsalProviderActionType.UNBLOCK_INPROGRESS:
117
+ if (previousState.inProgress === msalBrowser.InteractionStatus.Startup) {
118
+ newInProgress = msalBrowser.InteractionStatus.None;
119
+ payload.logger.info("MsalProvider - handleRedirectPromise resolved, setting inProgress to 'none'");
120
+ }
121
+
122
+ break;
123
+
124
+ case MsalProviderActionType.EVENT:
125
+ const message = payload.message;
126
+ const status = msalBrowser.EventMessageUtils.getInteractionStatusFromEvent(message, previousState.inProgress);
127
+
128
+ if (status) {
129
+ payload.logger.info(`MsalProvider - ${message.eventType} results in setting inProgress from ${previousState.inProgress} to ${status}`);
130
+ newInProgress = status;
131
+ }
132
+
133
+ break;
134
+
135
+ default:
136
+ throw new Error(`Unknown action type: ${type}`);
137
+ }
138
+
139
+ const currentAccounts = payload.instance.getAllAccounts();
140
+
141
+ if (!accountArraysAreEqual(currentAccounts, previousState.accounts)) {
142
+ payload.logger.info("MsalProvider - updating account state");
143
+ newAccounts = currentAccounts;
144
+ } else {
145
+ payload.logger.verbose("MsalProvider - no account changes");
146
+ }
147
+
148
+ return { ...previousState,
149
+ inProgress: newInProgress,
150
+ accounts: newAccounts
151
+ };
152
+ };
153
+ /**
154
+ * MSAL context provider component. This must be rendered above any other components that use MSAL.
155
+ */
156
+
157
+
72
158
  function MsalProvider({
73
159
  instance,
74
160
  children
@@ -79,56 +165,24 @@ function MsalProvider({
79
165
 
80
166
  const logger = React.useMemo(() => {
81
167
  return instance.getLogger().clone(name, version);
82
- }, [instance]); // State hook to store accounts
83
-
84
- const [accounts, setAccounts] = React.useState([]); // State hook to store in progress value
85
-
86
- const [inProgress, setInProgress] = React.useState(msalBrowser.InteractionStatus.Startup); // Mutable object used in the event callback
87
-
88
- const inProgressRef = React.useRef(inProgress);
89
- React.useEffect(() => {
90
- const callbackId = instance.addEventCallback(message => {
91
- switch (message.eventType) {
92
- case msalBrowser.EventType.ACCOUNT_ADDED:
93
- case msalBrowser.EventType.ACCOUNT_REMOVED:
94
- case msalBrowser.EventType.LOGIN_SUCCESS:
95
- case msalBrowser.EventType.SSO_SILENT_SUCCESS:
96
- case msalBrowser.EventType.HANDLE_REDIRECT_END:
97
- case msalBrowser.EventType.LOGIN_FAILURE:
98
- case msalBrowser.EventType.SSO_SILENT_FAILURE:
99
- case msalBrowser.EventType.LOGOUT_END:
100
- case msalBrowser.EventType.ACQUIRE_TOKEN_SUCCESS:
101
- case msalBrowser.EventType.ACQUIRE_TOKEN_FAILURE:
102
- const currentAccounts = instance.getAllAccounts();
103
-
104
- if (!accountArraysAreEqual(currentAccounts, accounts)) {
105
- logger.info("MsalProvider - updating account state");
106
- setAccounts(currentAccounts);
107
- } else {
108
- logger.info("MsalProvider - no account changes");
109
- }
110
-
111
- break;
112
- }
113
- });
114
- logger.verbose(`MsalProvider - Registered event callback with id: ${callbackId}`);
115
- return () => {
116
- // Remove callback when component unmounts or accounts change
117
- if (callbackId) {
118
- logger.verbose(`MsalProvider - Removing event callback ${callbackId}`);
119
- instance.removeEventCallback(callbackId);
120
- }
168
+ }, [instance]);
169
+ const [state, updateState] = React.useReducer(reducer, undefined, () => {
170
+ // Lazy initialization of the initial state
171
+ return {
172
+ inProgress: msalBrowser.InteractionStatus.Startup,
173
+ accounts: instance.getAllAccounts()
121
174
  };
122
- }, [instance, accounts, logger]);
175
+ });
123
176
  React.useEffect(() => {
124
177
  const callbackId = instance.addEventCallback(message => {
125
- const status = msalBrowser.EventMessageUtils.getInteractionStatusFromEvent(message, inProgressRef.current);
126
-
127
- if (status !== null) {
128
- logger.info(`MsalProvider - ${message.eventType} results in setting inProgress from ${inProgressRef.current} to ${status}`);
129
- inProgressRef.current = status;
130
- setInProgress(status);
131
- }
178
+ updateState({
179
+ payload: {
180
+ instance,
181
+ logger,
182
+ message
183
+ },
184
+ type: MsalProviderActionType.EVENT
185
+ });
132
186
  });
133
187
  logger.verbose(`MsalProvider - Registered event callback with id: ${callbackId}`);
134
188
  instance.handleRedirectPromise().catch(() => {
@@ -139,12 +193,16 @@ function MsalProvider({
139
193
  * If handleRedirectPromise returns a cached promise the necessary events may not be fired
140
194
  * This is a fallback to prevent inProgress from getting stuck in 'startup'
141
195
  */
142
- if (inProgressRef.current === msalBrowser.InteractionStatus.Startup) {
143
- inProgressRef.current = msalBrowser.InteractionStatus.None;
144
- setInProgress(msalBrowser.InteractionStatus.None);
145
- }
196
+ updateState({
197
+ payload: {
198
+ instance,
199
+ logger
200
+ },
201
+ type: MsalProviderActionType.UNBLOCK_INPROGRESS
202
+ });
146
203
  });
147
204
  return () => {
205
+ // Remove callback when component unmounts or accounts change
148
206
  if (callbackId) {
149
207
  logger.verbose(`MsalProvider - Removing event callback ${callbackId}`);
150
208
  instance.removeEventCallback(callbackId);
@@ -153,8 +211,8 @@ function MsalProvider({
153
211
  }, [instance, logger]);
154
212
  const contextValue = {
155
213
  instance,
156
- inProgress,
157
- accounts,
214
+ inProgress: state.inProgress,
215
+ accounts: state.accounts,
158
216
  logger
159
217
  };
160
218
  return React__default.createElement(MsalContext.Provider, {
@@ -177,61 +235,9 @@ const useMsal = () => React.useContext(MsalContext);
177
235
  * Licensed under the MIT License.
178
236
  */
179
237
 
180
- function getAccount(instance, accountIdentifiers) {
181
- const allAccounts = instance.getAllAccounts();
182
-
183
- if (allAccounts.length > 0 && (accountIdentifiers.homeAccountId || accountIdentifiers.localAccountId || accountIdentifiers.username)) {
184
- const matchedAccounts = allAccounts.filter(accountObj => {
185
- if (accountIdentifiers.username && accountIdentifiers.username.toLowerCase() !== accountObj.username.toLowerCase()) {
186
- return false;
187
- }
188
-
189
- if (accountIdentifiers.homeAccountId && accountIdentifiers.homeAccountId.toLowerCase() !== accountObj.homeAccountId.toLowerCase()) {
190
- return false;
191
- }
192
-
193
- if (accountIdentifiers.localAccountId && accountIdentifiers.localAccountId.toLowerCase() !== accountObj.localAccountId.toLowerCase()) {
194
- return false;
195
- }
196
-
197
- return true;
198
- });
199
- return matchedAccounts[0] || null;
200
- } else {
201
- return null;
202
- }
203
- }
204
- /**
205
- * Given 1 or more accountIdentifiers, returns the Account object if the user is signed-in
206
- * @param accountIdentifiers
207
- */
208
-
209
-
210
- function useAccount(accountIdentifiers) {
211
- const {
212
- instance,
213
- inProgress
214
- } = useMsal();
215
- const initialStateValue = inProgress === msalBrowser.InteractionStatus.Startup ? null : getAccount(instance, accountIdentifiers);
216
- const [account, setAccount] = React.useState(initialStateValue);
217
- React.useEffect(() => {
218
- const currentAccount = getAccount(instance, accountIdentifiers);
219
-
220
- if (!msalBrowser.AccountEntity.accountInfoIsEqual(account, currentAccount, true)) {
221
- setAccount(currentAccount);
222
- }
223
- }, [inProgress, accountIdentifiers, instance, account]);
224
- return account;
225
- }
226
-
227
- /*
228
- * Copyright (c) Microsoft Corporation. All rights reserved.
229
- * Licensed under the MIT License.
230
- */
231
-
232
- function isAuthenticated(allAccounts, account, matchAccount) {
238
+ function isAuthenticated(allAccounts, matchAccount) {
233
239
  if (matchAccount && (matchAccount.username || matchAccount.homeAccountId || matchAccount.localAccountId)) {
234
- return !!account;
240
+ return !!getAccountByIdentifiers(allAccounts, matchAccount);
235
241
  }
236
242
 
237
243
  return allAccounts.length > 0;
@@ -244,15 +250,12 @@ function isAuthenticated(allAccounts, account, matchAccount) {
244
250
 
245
251
  function useIsAuthenticated(matchAccount) {
246
252
  const {
247
- accounts: allAccounts,
248
- inProgress
253
+ accounts: allAccounts
249
254
  } = useMsal();
250
- const account = useAccount(matchAccount || {});
251
- const initialStateValue = inProgress === msalBrowser.InteractionStatus.Startup ? false : isAuthenticated(allAccounts, account, matchAccount);
252
- const [hasAuthenticated, setHasAuthenticated] = React.useState(initialStateValue);
255
+ const [hasAuthenticated, setHasAuthenticated] = React.useState(() => isAuthenticated(allAccounts, matchAccount));
253
256
  React.useEffect(() => {
254
- setHasAuthenticated(isAuthenticated(allAccounts, account, matchAccount));
255
- }, [allAccounts, account, matchAccount]);
257
+ setHasAuthenticated(isAuthenticated(allAccounts, matchAccount));
258
+ }, [allAccounts, matchAccount]);
256
259
  return hasAuthenticated;
257
260
  }
258
261
 
@@ -320,13 +323,86 @@ function UnauthenticatedTemplate({
320
323
  return null;
321
324
  }
322
325
 
326
+ /*
327
+ * Copyright (c) Microsoft Corporation. All rights reserved.
328
+ * Licensed under the MIT License.
329
+ */
330
+
331
+ function getAccount(instance, accountIdentifiers) {
332
+ if (!accountIdentifiers || !accountIdentifiers.homeAccountId && !accountIdentifiers.localAccountId && !accountIdentifiers.username) {
333
+ // If no account identifiers are provided, return active account
334
+ return instance.getActiveAccount();
335
+ }
336
+
337
+ return getAccountByIdentifiers(instance.getAllAccounts(), accountIdentifiers);
338
+ }
339
+ /**
340
+ * Given 1 or more accountIdentifiers, returns the Account object if the user is signed-in
341
+ * @param accountIdentifiers
342
+ */
343
+
344
+
345
+ function useAccount(accountIdentifiers) {
346
+ const {
347
+ instance,
348
+ inProgress,
349
+ logger
350
+ } = useMsal();
351
+ const [account, setAccount] = React.useState(() => getAccount(instance, accountIdentifiers));
352
+ React.useEffect(() => {
353
+ setAccount(currentAccount => {
354
+ const nextAccount = getAccount(instance, accountIdentifiers);
355
+
356
+ if (!msalBrowser.AccountEntity.accountInfoIsEqual(currentAccount, nextAccount, true)) {
357
+ logger.info("useAccount - Updating account");
358
+ return nextAccount;
359
+ }
360
+
361
+ return currentAccount;
362
+ });
363
+ }, [inProgress, accountIdentifiers, instance, logger]);
364
+ return account;
365
+ }
366
+
367
+ /*
368
+ * Copyright (c) Microsoft Corporation. All rights reserved.
369
+ * Licensed under the MIT License.
370
+ */
371
+ const ReactAuthErrorMessage = {
372
+ invalidInteractionType: {
373
+ code: "invalid_interaction_type",
374
+ desc: "The provided interaction type is invalid."
375
+ },
376
+ unableToFallbackToInteraction: {
377
+ code: "unable_to_fallback_to_interaction",
378
+ desc: "Interaction is required but another interaction is already in progress. Please try again when the current interaction is complete."
379
+ }
380
+ };
381
+ class ReactAuthError extends msalBrowser.AuthError {
382
+ constructor(errorCode, errorMessage) {
383
+ super(errorCode, errorMessage);
384
+ Object.setPrototypeOf(this, ReactAuthError.prototype);
385
+ this.name = "ReactAuthError";
386
+ }
387
+
388
+ static createInvalidInteractionTypeError() {
389
+ return new ReactAuthError(ReactAuthErrorMessage.invalidInteractionType.code, ReactAuthErrorMessage.invalidInteractionType.desc);
390
+ }
391
+
392
+ static createUnableToFallbackToInteractionError() {
393
+ return new ReactAuthError(ReactAuthErrorMessage.unableToFallbackToInteraction.code, ReactAuthErrorMessage.unableToFallbackToInteraction.desc);
394
+ }
395
+
396
+ }
397
+
323
398
  /*
324
399
  * Copyright (c) Microsoft Corporation. All rights reserved.
325
400
  * Licensed under the MIT License.
326
401
  */
327
402
  /**
328
- * Invokes a login call if a user is not currently signed-in. Failed logins can be retried using the login callback returned.
329
- * Optionally provide a request object to be used in the login call.
403
+ * If a user is not currently signed in this hook invokes a login. Failed logins can be retried using the login callback returned.
404
+ * If a user is currently signed in this hook attempts to acquire a token. Subsequent token requests can use the acquireToken callback returned.
405
+ * Optionally provide a request object to be used in the login/acquireToken call.
330
406
  * Optionally provide a specific user that should be logged in.
331
407
  * @param interactionType
332
408
  * @param authenticationRequest
@@ -340,8 +416,28 @@ function useMsalAuthentication(interactionType, authenticationRequest, accountId
340
416
  logger
341
417
  } = useMsal();
342
418
  const isAuthenticated = useIsAuthenticated(accountIdentifiers);
343
- const [[result, error], setResponse] = React.useState([null, null]);
344
- const [hasBeenCalled, setHasBeenCalled] = React.useState(false);
419
+ const account = useAccount(accountIdentifiers);
420
+ const [[result, error], setResponse] = React.useState([null, null]); // Boolean used to check if interaction is in progress in acquireTokenSilent fallback. Use Ref instead of state to prevent acquireToken function from being regenerated on each change to interactionInProgress value
421
+
422
+ const interactionInProgress = React.useRef(inProgress !== msalBrowser.InteractionStatus.None);
423
+ React.useEffect(() => {
424
+ interactionInProgress.current = inProgress !== msalBrowser.InteractionStatus.None;
425
+ }, [inProgress]); // Flag used to control when the hook calls login/acquireToken
426
+
427
+ const shouldAcquireToken = React.useRef(true);
428
+ React.useEffect(() => {
429
+ if (!!error) {
430
+ // Errors should be handled by consuming component
431
+ shouldAcquireToken.current = false;
432
+ return;
433
+ }
434
+
435
+ if (!!result) {
436
+ // Token has already been acquired, consuming component/application is responsible for renewing
437
+ shouldAcquireToken.current = false;
438
+ return;
439
+ }
440
+ }, [error, result]);
345
441
  const login = React.useCallback(async (callbackInteractionType, callbackRequest) => {
346
442
  const loginType = callbackInteractionType || interactionType;
347
443
  const loginRequest = callbackRequest || authenticationRequest;
@@ -361,9 +457,59 @@ function useMsalAuthentication(interactionType, authenticationRequest, accountId
361
457
  return instance.ssoSilent(loginRequest);
362
458
 
363
459
  default:
364
- throw "Invalid interaction type provided.";
460
+ throw ReactAuthError.createInvalidInteractionTypeError();
365
461
  }
366
462
  }, [instance, interactionType, authenticationRequest, logger]);
463
+ const acquireToken = React.useCallback(async (callbackInteractionType, callbackRequest) => {
464
+ const fallbackInteractionType = callbackInteractionType || interactionType;
465
+ let tokenRequest;
466
+
467
+ if (callbackRequest) {
468
+ logger.trace("useMsalAuthentication - acquireToken - Using request provided in the callback");
469
+ tokenRequest = { ...callbackRequest
470
+ };
471
+ } else if (authenticationRequest) {
472
+ logger.trace("useMsalAuthentication - acquireToken - Using request provided in the hook");
473
+ tokenRequest = { ...authenticationRequest,
474
+ scopes: authenticationRequest.scopes || msalBrowser.OIDC_DEFAULT_SCOPES
475
+ };
476
+ } else {
477
+ logger.trace("useMsalAuthentication - acquireToken - No request object provided, using default request.");
478
+ tokenRequest = {
479
+ scopes: msalBrowser.OIDC_DEFAULT_SCOPES
480
+ };
481
+ }
482
+
483
+ if (!tokenRequest.account && account) {
484
+ logger.trace("useMsalAuthentication - acquireToken - Attaching account to request");
485
+ tokenRequest.account = account;
486
+ }
487
+
488
+ const getToken = async () => {
489
+ logger.verbose("useMsalAuthentication - Calling acquireTokenSilent");
490
+ return instance.acquireTokenSilent(tokenRequest).catch(async e => {
491
+ if (e instanceof msalBrowser.InteractionRequiredAuthError) {
492
+ if (!interactionInProgress.current) {
493
+ logger.error("useMsalAuthentication - Interaction required, falling back to interaction");
494
+ return login(fallbackInteractionType, tokenRequest);
495
+ } else {
496
+ logger.error("useMsalAuthentication - Interaction required but is already in progress. Please try again, if needed, after interaction completes.");
497
+ throw ReactAuthError.createUnableToFallbackToInteractionError();
498
+ }
499
+ }
500
+
501
+ throw e;
502
+ });
503
+ };
504
+
505
+ return getToken().then(response => {
506
+ setResponse([response, null]);
507
+ return response;
508
+ }).catch(e => {
509
+ setResponse([null, e]);
510
+ throw e;
511
+ });
512
+ }, [instance, interactionType, authenticationRequest, logger, account, login]);
367
513
  React.useEffect(() => {
368
514
  const callbackId = instance.addEventCallback(message => {
369
515
  switch (message.eventType) {
@@ -393,18 +539,27 @@ function useMsalAuthentication(interactionType, authenticationRequest, accountId
393
539
  };
394
540
  }, [instance, logger]);
395
541
  React.useEffect(() => {
396
- if (!hasBeenCalled && !error && !isAuthenticated && inProgress === msalBrowser.InteractionStatus.None) {
397
- logger.info("useMsalAuthentication - No user is authenticated, attempting to login"); // Ensure login is only called one time from within this hook, any subsequent login attempts should use the callback returned
398
-
399
- setHasBeenCalled(true);
400
- login().catch(() => {
401
- // Errors are handled by the event handler above
402
- return;
403
- });
542
+ if (shouldAcquireToken.current && inProgress === msalBrowser.InteractionStatus.None) {
543
+ shouldAcquireToken.current = false;
544
+
545
+ if (!isAuthenticated) {
546
+ logger.info("useMsalAuthentication - No user is authenticated, attempting to login");
547
+ login().catch(() => {
548
+ // Errors are saved in state above
549
+ return;
550
+ });
551
+ } else if (account) {
552
+ logger.info("useMsalAuthentication - User is authenticated, attempting to acquire token");
553
+ acquireToken().catch(() => {
554
+ // Errors are saved in state above
555
+ return;
556
+ });
557
+ }
404
558
  }
405
- }, [isAuthenticated, inProgress, error, hasBeenCalled, login, logger]);
559
+ }, [isAuthenticated, account, inProgress, login, acquireToken, logger]);
406
560
  return {
407
561
  login,
562
+ acquireToken,
408
563
  result,
409
564
  error
410
565
  };