Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions docs/prd/06-technical-platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,14 +133,19 @@ For safety, the backend should use GCS **preconditions** (`ifGenerationMatch`) w

### Authentication — Google Identity Platform

Players authenticate via Google Sign-In. This aligns with PRD 04's decision that player identity is an email address (via Google Auth).
OpenStars authentication rollout is staged to de-risk delivery:

- Frontend uses the Google Identity Services SDK for sign-in
- Backend validates Google ID tokens on each API request
- The `username` field in game state maps to the authenticated email
1. **UI sign-in gate first** (current): frontend uses Google Identity Services (GIS) and requires login before lobby access.
2. **Backend bearer-token validation later**: backend validates Google ID tokens and extracts identity server-side.

Identity model decisions remain the same:

- `username` in game state maps to authenticated email identity
- No custom auth system, no password storage

For local development, auth can be bypassed or mocked (see Local Development below).
During stage 1, the frontend maps the signed-in email to `X-Player` when calling the existing API (see PRD 50). This keeps endpoint contracts stable while backend authorisation work is pending.

For local development, auth can be bypassed or mocked when needed (see Local Development below).

## Docker Strategy

Expand Down
15 changes: 11 additions & 4 deletions docs/prd/50-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,29 @@ All endpoints are shown as full paths (e.g. `/api/v1/games`). The `/api/v1` pref

## Authentication

Phase 1 has **no authentication**. The player identity is passed via a request header on all player-scoped endpoints:
Current backend API auth is a transitional model:

- The backend still uses `X-Player` for player identity on player-scoped endpoints
- The frontend sign-in UX may require Google login before showing the games list (see PRD 60)
- During this transition, the frontend maps the signed-in Google email to `X-Player`
- The backend trusts `X-Player` and does not validate Google bearer tokens yet

The player identity is passed via a request header on player-scoped endpoints:

```
X-Player: {username}
```

The backend trusts this value — there is no token validation or identity verification. This keeps the initial implementation simple and removes any dependency on Google Identity or auth infrastructure.
The backend trusts this value — there is no token validation or identity verification in this phase.

**Examples:**
- `GET /api/v1/games/my-game/state` with `X-Player: tim` — Tim's view of the game
- `POST /api/v1/games/my-game/commands` with `X-Player: matt` — submit commands as Matt
- `GET /api/v1/games/my-game/commands` with `X-Player: tim` — retrieve Tim's submitted commands

The `X-Player` header is required on all player-scoped and participant-gated endpoints: `GET /games/{game_id}`, `GET /state`, `GET /galaxy`, `GET /commands`, `POST /commands`, and `POST /resolve`. It is optional on `GET /games` (filters to games containing that player; omit to list all games).
The `X-Player` header is required on all player-scoped and participant-gated endpoints: `GET /games/{game_id}`, `GET /state`, `GET /galaxy`, `GET /commands`, `POST /commands`, and `POST /resolve`. It is optional on `GET /games` (filters to games containing that player; omit to list all games in non-production/dev scenarios).

Authentication (Google Identity) will be added in Phase 5 (Multiplayer), replacing `X-Player` with an `Authorization: Bearer <token>` header and server-side identity extraction. The switch is a single middleware change — no endpoint signatures need updating.
Backend authentication (Google bearer token validation) will be added in a follow-up phase, replacing `X-Player` with `Authorization: Bearer <token>` and server-side identity extraction. Endpoint paths and payloads do not need to change for that migration.

---

Expand Down
29 changes: 28 additions & 1 deletion docs/prd/60-ui-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,33 @@ Reference: `docs/references/stars-1995-screenshot-51464.jpg`
- **UI panels:** React + TypeScript + Tailwind CSS + shadcn/ui components
- **State management:** React context or Zustand — TBD during implementation, keep it simple
- **Layout:** CSS Grid for the overall structure, absolute positioning for map overlays
- **Identity UI:** Google Identity Services (GIS) for frontend sign-in

## Access and Sign-in Gate

The frontend must require Google sign-in **before** showing the game lobby/games list.

- Initial route shows a dedicated sign-in screen with OpenStars! branding and a single primary action: **Sign in with Google**
- Unauthenticated users cannot view the games list, create a game, or open any game route
- On successful sign-in, the user is redirected to the lobby (games list)
- Sign out returns the user to the sign-in screen and clears in-memory lobby/game UI state

### Transitional architecture (UI now, backend authorisation later)

The sign-in gate is introduced in the UI before backend token validation is implemented.

- Frontend obtains Google identity (email + display name) from GIS
- Frontend continues to call existing API endpoints that currently use `X-Player`
- `X-Player` is populated from the signed-in Google email during this transition period
- Backend remains unchanged in this phase (no bearer-token validation yet)

This keeps the UX and route-guard behaviour aligned with the eventual multiplayer auth model while avoiding a coupled frontend/backend migration.

### Error and loading states

- While GIS initialises, show a loading state on the sign-in screen
- If GIS fails to load or sign-in fails, show a clear retryable error message
- If stored sign-in state is invalid/expired, return to sign-in screen and require login again

## Screen Layout

Expand Down Expand Up @@ -140,11 +167,11 @@ Phase 2 (Basic UI) implements the minimum needed to interact with the Phase 1 en
- Research allocation
- Race/trait configuration
- Battle replay viewer
- Game lobby / game creation UI (Phase 5 — multiplayer)
- Chat / messaging between players
- Notifications (email/push for "it's your turn")
- Planet habitability visualisation
- Minimap
- Backend bearer-token validation and authorisation enforcement (follow-up phase)

## Screen Size

Expand Down
71 changes: 71 additions & 0 deletions tasks/2026-04-20-google-auth-ui-gate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Google Auth UI Gate for Lobby Access

**PRDs:**
- [60-ui-overview.md](../docs/prd/60-ui-overview.md) — Access and Sign-in Gate
- [50-api.md](../docs/prd/50-api.md) — transitional `X-Player` auth model
- [06-technical-platform.md](../docs/prd/06-technical-platform.md) — staged Google Identity rollout

Implement Google sign-in in the frontend so users must authenticate before they can access the games list (lobby) or enter a game route. Backend bearer-token validation is explicitly out of scope for this task.

---

## Step 1 — Frontend auth foundations and configuration

- [ ] Add frontend auth configuration for Google Identity Services (client ID, environment wiring, and startup validation)
- [ ] Add an auth domain model (`unauthenticated` / `loading` / `authenticated` / `error`) and shared types for signed-in user identity
- [ ] Add a small auth service layer that wraps GIS initialisation and sign-in/sign-out operations
- [ ] Persist minimal sign-in session state appropriate for SPA reloads (without storing sensitive tokens long-term)
- [ ] Unit tests:
- Auth service initialises GIS successfully
- Auth service returns a retryable error when GIS fails to load
- Auth state transitions are deterministic for success/failure/sign-out paths

## Step 2 — Route guarding and login screen UX

- [ ] Add a dedicated login screen as the default unauthenticated entry point
- [ ] Gate lobby (games list), game creation, and game routes behind authentication
- [ ] Redirect authenticated users from login screen to lobby
- [ ] Redirect unauthenticated users trying to access protected routes back to login
- [ ] Add loading and error UI states on the login screen for GIS initialisation/sign-in failures
- [ ] Component/router tests:
- Unauthenticated user sees login screen and cannot access lobby content
- Authenticated user is redirected to lobby
- Protected route navigation bounces unauthenticated users to login
- Login error state renders retry affordance

## Step 3 — API client integration with transitional identity header

- [ ] Update frontend API client wiring so authenticated identity drives `X-Player`
- [ ] Use signed-in Google email as the `X-Player` value for existing endpoints
- [ ] Ensure API calls are blocked or short-circuited while auth is unresolved/unauthenticated
- [ ] Preserve existing backend contract (no bearer-token changes in this task)
- [ ] Unit tests:
- API client sends `X-Player` header from authenticated email
- API client omits protected requests when user is signed out
- Existing game list/game state calls continue to decode successfully under authenticated flow

## Step 4 — Header/session controls and sign-out behaviour

- [ ] Add signed-in identity display in lobby/top-level UI (email or display name)
- [ ] Add sign-out action accessible from lobby/game shell
- [ ] On sign-out, clear frontend auth/session state and return to login screen
- [ ] Ensure stale game/lobby data is not shown after sign-out
- [ ] Component/state tests:
- Sign-out clears auth state and triggers login redirect
- Post sign-out render does not expose previously loaded game list data

## Step 5 — Integration coverage and documentation touch-ups

- [ ] Add/update frontend integration tests for the full login → lobby → sign-out flow
- [ ] Update frontend developer documentation for required Google client ID configuration and local-dev auth behaviour
- [ ] Confirm lint/typecheck/tests pass for frontend workspace
- [ ] Verification commands (from `frontend/`):
- `npm run lint`
- `npm run typecheck`
- `npm test`

## Notes

- Backend authorisation/token validation is intentionally deferred; follow-up work will migrate from `X-Player` to bearer tokens.
- Keep implementation compatible with existing local development workflow.
- Use British English in UI copy and docs where practical.