The application's TopBar was showing "Connect" button even when users were logged in. This was because the AuthContext was:
- Checking for
auth_tokenin localStorage (which Appwrite doesn't use) - Not actually checking Appwrite's session state
- Not refreshing when users navigated back from authentication
- Now uses Appwrite's
account.get()API to check session - Implements
getCurrentUserId()to verify active session - Fetches user profile with
getCurrentUserProfile() - Integrates with session sync service for real-time updates
- Properly handles logout by clearing Appwrite session
Key Changes:
// Before: Checking localStorage (WRONG)
const hasAuthToken = localStorage.getItem('auth_token')
// After: Checking Appwrite session (CORRECT)
const userId = await getCurrentUserId()
if (userId) {
// User is authenticated
}New service that monitors session state changes:
- Listens for visibility changes (browser tab focus)
- Periodically checks session (every 60 seconds)
- Notifies all listeners when session changes
- Works across all components without prop drilling
Features:
getCurrentSession()- Returns current session dataonSessionChange()- Subscribe to session changesinitializeSessionMonitoring()- Start automatic monitoring
- Shows user's email when logged in
- Displays loading state while checking auth
- Properly redirects after logout
- Shows full user email instead of generic "Account"
Changes:
// Before
{isAuthenticated ? 'Account' : 'Account'}
// After
{isAuthenticated && user?.email ? user.email : (loading ? 'Loading...' : 'Account')}New hook for components to refresh auth state:
export function useAuthRefresh() {
// Automatically refreshes auth when component mounts
// and when browser tab becomes visible
}
export function useAuthState() {
// Returns isAuthenticated, loading, user, isReady, hasUser
}┌─────────────────────────────────────┐
│ App Loads / User Navigates Back │
└─────────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────┐
│ AuthContext Mounts │
│ • Calls checkAppwriteSession() │
│ • Gets Appwrite session │
└─────────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Appwrite Session Check │
│ • getCurrentUserId() │
│ • getCurrentUserProfile() │
└─────────────────┬───────────────────┘
│
┌─────────┴─────────┐
│ │
▼ ▼
┌──────┐ ┌──────────┐
│ Auth │ │ No Auth │
└──┬───┘ └─────┬────┘
│ │
▼ ▼
Set User Clear User
Show Dropdown Show Connect
Once authenticated, the app:
- Monitors visibility - Refreshes when browser tab becomes active
- Checks periodically - Every 60 seconds to catch session changes
- Notifies subscribers - All components using
useAuth()get updates - Handles logout - Clears Appwrite session and local state
All components automatically get proper auth state via useAuth():
const { isAuthenticated, user, loading, logout } = useAuth()TopBar.tsx- Shows user info or Connect buttonpage.tsx- Redirects to auth if not logged inPaymentProfile.tsx- Shows wallet connectionDashboardClient.tsx- Displays user profile
Must have configured:
NEXT_PUBLIC_APPWRITE_ENDPOINT- Appwrite server URLNEXT_PUBLIC_APPWRITE_PROJECT_ID- Project IDNEXT_PUBLIC_APPWRITE_DB_ID- Database IDNEXT_PUBLIC_APPWRITE_COLLECTION_USERS- Users collection
-
Login
- Navigate to app
- Click "Connect" in dropdown
- Complete login
- TopBar should show email (not "Connect")
-
Refresh
- Page reload (F5)
- TopBar should still show email
- No re-login needed
-
Navigate Away and Back
- Open another tab
- Return to app tab
- TopBar should still show email
-
Logout
- Click dropdown
- Click "Sign out"
- Redirected to logout
- TopBar shows "Connect" again
-
Session Persistence
- Close browser
- Reopen app
- If session cookie exists, TopBar shows email
- Session restored automatically
- Session checking: 60-second interval (not on every render)
- Profile fetching: Only once per session
- User data: Cached in React state
- No localStorage: Uses Appwrite's native cookies
- Visibility-based: Only checks when tab is active
src/contexts/AuthContext.tsx- Complete rewritesrc/components/layout/TopBar.tsx- Display improvementssrc/lib/sessionSync.ts- NEW: Session monitoringsrc/hooks/useAuthRefresh.ts- NEW: Auth refresh hook
If your app was using the old auth_token localStorage approach:
- No breaking changes - All components continue to work
- New auth state -
isAuthenticatednow reflects actual session - User data -
userobject now populated with Appwrite user data - Logout flow - Now properly clears Appwrite session
Check browser console for:
- Session check errors
- Profile fetch warnings
- Session monitoring events
"Still showing Connect after login"
- Clear browser cookies
- Check Appwrite endpoint in env
- Verify Appwrite session cookie is being set
"Session not persisting after refresh"
- Check browser allows cookies
- Verify Appwrite session is valid
- Check console for CORS errors
"User email not showing"
- Verify Appwrite user has email field
- Check user profile was fetched
- Look for profile fetch errors in console
- Add refresh token rotation
- Implement session timeout warnings
- Add biometric auth support
- Social login integration
- Session across devices