Authentication

The browser client authenticates users through AWS Cognito via aws-amplify v6. Sign-in uses the Cognito hosted UI (OAuth authorization code flow with federated identity providers).

Configuration

Amplify is configured once at app startup in amplifyAuth.js, called from index.js:

Redirect URLs come from COGNITO_REDIRECT_LOGIN and COGNITO_REDIRECT_LOGOUT. See Configuration.

polyfills.js imports aws-amplify/auth/enable-oauth-listener so OAuth callbacks complete in production Vite builds (the listener must live in the root bundle, not a lazy chunk).

Sign-in flow

  1. User clicks login → signInWithRedirect() via redirectToSignIn() (navbar ProfileMenu.js when logged out).
  2. Browser redirects to Cognito hosted UI.
  3. On success, Cognito redirects back with an authorization code; Amplify exchanges it for tokens.
  4. resolveAuthSession() stores the JWT and normalized identity fields (userId, username, email) in Zustand authSession; UI components read them via useAuthSession().

Session bootstrap

Skeleton calls resolveAuthSession() on load:

Token refresh

getAuthTokenFromSession() returns a cached JWT while it is still valid (with a 5-minute buffer before expiry). When the token is stale or missing, it silently calls fetchAuthSession() again so Amplify can refresh the ID token without flashing the login UI.

callAuthApi retries once with a forced session refresh on HTTP 401/403 before redirecting to Cognito.

Sign-out

ProfileMenu.js and UserSettingsModal.js set sessionStorage.intentionalLogout = "1" before signOut() so the expiry handler does not immediately re-login.

User profile (globalMe)

After login, useProfileBootstrap calls fetchProfile() (me_profile), which populates Zustand globalMe (bots, settings, activeGames, etc.). NotificationBell.js calls fetchNotifications() (list_notifications) once for the navbar feed. Me.js on / calls fetchDashboard() (me_dashboard) for games and challenges and fetchNotifications() in parallel as a gap filler; WebSocket notification messages trigger a debounced fetchNotifications() while connected (see WebSockets).

New user onboarding

If the backend returns an incomplete profile, NewProfile.js prompts the user to set a display name and preferences.

Token usage

Profile updates

Email changes go through Amplify v6 attribute APIs (updateUserAttribute, confirmUserAttribute) in UserSettingsModal, not the node-backend authQuery layer.

Avatar customization (DiceBear style + seed) is saved via update_user_settings as settings.all.profile.avatar and mirrored on the public user list for player profiles. See User Settings → Avatar in UserSettingsModal.js and UserAvatar.js.

Cognito setup (ops)

Pool configuration, callback URLs, and identity providers are documented in Backend deployment. Dev and prod use separate pools; tokens are not interchangeable across stages.

Related