@proveanything/smartlinks-auth-ui 0.1.16 → 0.1.18

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.
package/dist/index.js CHANGED
@@ -11245,6 +11245,9 @@ const AuthProvider = ({ children, proxyMode = false, accountCacheTTL = 5 * 60 *
11245
11245
  const [accountInfo, setAccountInfo] = React.useState(null);
11246
11246
  const [isLoading, setIsLoading] = React.useState(true);
11247
11247
  const callbacksRef = React.useRef(new Set());
11248
+ // Initialization guards to prevent race conditions on hot reload
11249
+ const initializingRef = React.useRef(false);
11250
+ const initializedRef = React.useRef(false);
11248
11251
  // Notify all subscribers of auth state changes
11249
11252
  const notifyAuthStateChange = React.useCallback((type, currentUser, currentToken, currentAccountData, currentAccountInfo) => {
11250
11253
  callbacksRef.current.forEach(callback => {
@@ -11264,6 +11267,13 @@ const AuthProvider = ({ children, proxyMode = false, accountCacheTTL = 5 * 60 *
11264
11267
  }, []);
11265
11268
  // Initialize auth state - different behavior for proxy mode vs standalone mode
11266
11269
  React.useEffect(() => {
11270
+ // Prevent concurrent initialization (race condition fix)
11271
+ if (initializingRef.current || initializedRef.current) {
11272
+ console.log('[AuthContext] Skipping initialization - already in progress or completed');
11273
+ return;
11274
+ }
11275
+ let isMounted = true;
11276
+ initializingRef.current = true;
11267
11277
  const initializeAuth = async () => {
11268
11278
  try {
11269
11279
  if (proxyMode) {
@@ -11275,7 +11285,7 @@ const AuthProvider = ({ children, proxyMode = false, accountCacheTTL = 5 * 60 *
11275
11285
  // empty/undefined if no user is logged in
11276
11286
  const accountAny = accountResponse;
11277
11287
  const hasValidSession = accountAny?.uid && accountAny.uid.length > 0;
11278
- if (hasValidSession) {
11288
+ if (hasValidSession && isMounted) {
11279
11289
  // User is logged in with valid account
11280
11290
  const userFromAccount = {
11281
11291
  uid: accountAny.uid,
@@ -11289,14 +11299,18 @@ const AuthProvider = ({ children, proxyMode = false, accountCacheTTL = 5 * 60 *
11289
11299
  console.log('[AuthContext] Proxy mode: initialized from parent account, uid:', accountAny.uid);
11290
11300
  notifyAuthStateChange('LOGIN', userFromAccount, null, accountResponse, accountResponse);
11291
11301
  }
11292
- else {
11302
+ else if (isMounted) {
11293
11303
  console.log('[AuthContext] Proxy mode: no valid session (no uid), awaiting login');
11294
11304
  }
11295
11305
  }
11296
11306
  catch (error) {
11297
11307
  console.log('[AuthContext] Proxy mode: auth.getAccount() failed, awaiting login:', error);
11298
11308
  }
11299
- setIsLoading(false);
11309
+ if (isMounted) {
11310
+ setIsLoading(false);
11311
+ initializedRef.current = true;
11312
+ initializingRef.current = false;
11313
+ }
11300
11314
  return;
11301
11315
  }
11302
11316
  // STANDALONE MODE: Load from persistent storage
@@ -11304,28 +11318,48 @@ const AuthProvider = ({ children, proxyMode = false, accountCacheTTL = 5 * 60 *
11304
11318
  const storedUser = await tokenStorage.getUser();
11305
11319
  const storedAccountData = await tokenStorage.getAccountData();
11306
11320
  if (storedToken && storedUser) {
11307
- setToken(storedToken.token);
11308
- setUser(storedUser);
11309
- setAccountData(storedAccountData);
11310
- // Set bearer token in global Smartlinks SDK via auth.verifyToken
11311
- smartlinks__namespace.auth.verifyToken(storedToken.token).catch(err => {
11312
- console.warn('Failed to restore bearer token on init:', err);
11313
- });
11321
+ // Verify token FIRST before setting state
11322
+ try {
11323
+ console.log('[AuthContext] Verifying stored token...');
11324
+ await smartlinks__namespace.auth.verifyToken(storedToken.token);
11325
+ // Only set state if verification succeeded and component still mounted
11326
+ if (isMounted) {
11327
+ setToken(storedToken.token);
11328
+ setUser(storedUser);
11329
+ setAccountData(storedAccountData);
11330
+ console.log('[AuthContext] Session restored successfully');
11331
+ }
11332
+ }
11333
+ catch (err) {
11334
+ console.warn('[AuthContext] Token verification failed, clearing stored credentials:', err);
11335
+ await tokenStorage.clearAll();
11336
+ // Don't set user state - leave as logged out
11337
+ }
11314
11338
  }
11315
11339
  // Load cached account info if available
11316
- const cachedAccountInfo = await tokenStorage.getAccountInfo();
11317
- if (cachedAccountInfo && !cachedAccountInfo.isStale) {
11318
- setAccountInfo(cachedAccountInfo.data);
11340
+ if (isMounted) {
11341
+ const cachedAccountInfo = await tokenStorage.getAccountInfo();
11342
+ if (cachedAccountInfo && !cachedAccountInfo.isStale) {
11343
+ setAccountInfo(cachedAccountInfo.data);
11344
+ }
11319
11345
  }
11320
11346
  }
11321
11347
  catch (error) {
11322
- console.error('Failed to initialize auth from storage:', error);
11348
+ console.error('[AuthContext] Failed to initialize auth from storage:', error);
11323
11349
  }
11324
11350
  finally {
11325
- setIsLoading(false);
11351
+ if (isMounted) {
11352
+ setIsLoading(false);
11353
+ initializedRef.current = true;
11354
+ initializingRef.current = false;
11355
+ }
11326
11356
  }
11327
11357
  };
11328
11358
  initializeAuth();
11359
+ // Cleanup for hot reload
11360
+ return () => {
11361
+ isMounted = false;
11362
+ };
11329
11363
  }, [proxyMode, notifyAuthStateChange]);
11330
11364
  // Listen for parent auth state changes (proxy mode only)
11331
11365
  React.useEffect(() => {