@azure/msal-react 1.2.0 → 1.3.2

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