Skip to content

Suggest display name on registration + allow login by email or username #46

Description

@amrtgaber

Currently, password registrants land with display_name = null and show up as their raw email everywhere (navbar.tsx already falls back: {auth.displayName ?? auth.email}). Google and Steam OAuth users typically get a display_name populated from the provider's profile, but the gap is real for password sign-ups.

Goal

Capture or suggest a display name without blocking the registration or post-OAuth flow. Also add a "username" identity that can be used to log in alongside email.

Scope

Frontend (this repo)

  1. Optional display-name field on /register — between the email and password inputs. Empty submission is fine; backend already accepts null. Helper text: "What others will see — you can change this later."
  2. Nudge banner on /profile when display_name is null — same shape as the existing consent-stale banner in profile-page.tsx. Copy idea: "You're showing up as your email. Pick a display name to personalize your account." Dismissible per session via localStorage.
  3. Login by email OR usernamelogin-page.tsx's email input becomes "Email or username". Backend handles the lookup; frontend just sends whatever the user typed. Form validation drops the type="email" constraint or makes it conditional.

Backend (auth-api, separate ticket needed)

The API doesn't currently have a username concept distinct from display_name. Open questions for the backend:

  • Is username the same column as display_name, or separate?
    • Same: display_name becomes unique (case-insensitive), with username-style validation (alphanumeric + _ + -, length cap). Simpler data model but constrains display-name freedom.
    • Separate: new username column, unique, used for login. display_name stays freeform. More flexibility, slightly more UI.
  • Default value: per Daisy's note, default to the email (or email's local-part) as the initial username, with the option to override later. Probably the local-part is what people expect (alice@example.comalice).
  • Email change syncs username when identical: if the user hasn't customized their username and changes their email, the username should follow. (Email change isn't implemented yet — flag this so it's not lost.)
  • /auth/jwt/login would need to accept either format. FastAPI-Users' default username field is the email; we'd need to override the user manager's authenticate method.

Constraint: don't break the cross-origin redirect flow

When a user is at a consumer app (e.g. hera-streamer-invitational-2026.criticalbit.gg) and clicks "Sign in", they land at auth.criticalbit.gg/login?redirect=https://hera-… and after a successful sign-in get bounced back. New users registering through this flow must not be interrupted by a forced onboarding step — the banner approach on /profile is fine (they may never see it before bouncing out), a modal/forced-pick page is not.

register-page.tsx currently does not preserve the ?redirect= param across the register→login→/profile sequence — that's a separate bug, but a fix here might want to handle it.

Out of scope / explicit non-goals

  • Forced display-name picker as an onboarding step. Banner is the chosen approach (lower friction, doesn't block redirect flow).
  • Email change UI (not implemented yet — but the username-syncs-with-email rule should be captured for whoever picks that up).
  • Username uniqueness migration for existing users (probably need a backfill; depends on the same-vs-separate decision above).

Order of operations

  1. Backend designs username (same vs separate from display_name), ships the auth-by-username support and the email-change sync rule.
  2. This repo adds the optional /register field (works regardless of Add auth pages (login, register, profile, Google callback) #1).
  3. This repo adds the /profile nudge banner (works regardless of Add auth pages (login, register, profile, Google callback) #1).
  4. This repo updates /login to accept email-or-username (depends on Add auth pages (login, register, profile, Google callback) #1).

Steps 2 and 3 are mechanically simple and can ship today; 1 and 4 are coupled.

Files likely touched (this repo)

  • src/pages/register/register-page.tsx — add optional input
  • src/pages/profile/profile-page.tsx — add nudge banner
  • src/pages/login/login-page.tsx — relabel email field to "email or username", drop type="email"
  • src/lib/auth.tsx — no change needed unless display_name becomes the username
  • New companion issue on ag-tech-group/criticalbit-auth-api for the backend work

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions