# S02: [A] Creator Authentication + Dashboard Shell — UAT

**Milestone:** M019
**Written:** 2026-04-03T22:04:22.117Z

# S02 UAT: Creator Authentication + Dashboard Shell

## Preconditions
- Chrysopedia stack running on ub01 (docker compose up)
- Alembic migration 016 applied (`docker exec chrysopedia-api alembic upgrade head`)
- Seed invite code created (`CHRYSOPEDIA-ALPHA-2026` with 100 uses)
- Frontend rebuilt and deployed

---

## TC-01: Registration with valid invite code
1. Navigate to `/register`
2. Enter invite code: `CHRYSOPEDIA-ALPHA-2026`
3. Enter email: `testcreator@example.com`
4. Enter display name: `Test Creator`
5. Enter password: `SecurePass123!` and confirm
6. Click Register

**Expected:** Registration succeeds, redirected to `/login` with success message.

## TC-02: Registration with invalid invite code
1. Navigate to `/register`
2. Enter invite code: `INVALID-CODE`
3. Fill remaining fields with valid data
4. Click Register

**Expected:** 403 error displayed — "Invalid or expired invite code"

## TC-03: Registration with duplicate email
1. Complete TC-01 first
2. Navigate to `/register` again
3. Use same email `testcreator@example.com` with valid invite code
4. Click Register

**Expected:** 409 error displayed — "Email already registered"

## TC-04: Login with valid credentials
1. Navigate to `/login`
2. Enter email: `testcreator@example.com`
3. Enter password: `SecurePass123!`
4. Click Login

**Expected:** Redirected to `/creator/dashboard`. Header nav shows display name, Dashboard link, and Logout button.

## TC-05: Login with wrong password
1. Navigate to `/login`
2. Enter email: `testcreator@example.com`
3. Enter password: `WrongPassword!`
4. Click Login

**Expected:** 401 error displayed — "Invalid email or password"

## TC-06: Session persistence across page reload
1. Complete TC-04 (logged in)
2. Refresh the page (F5)

**Expected:** User remains logged in. Dashboard/nav still shows authenticated state. No redirect to /login.

## TC-07: Dashboard shell layout
1. Log in and navigate to `/creator/dashboard`
2. Observe sidebar nav and main content

**Expected:**
- Left sidebar with: Dashboard (active/highlighted), Content (disabled/placeholder), Settings (clickable link)
- Main content: Welcome message with user's display name
- Placeholder cards mentioning future analytics

## TC-08: Navigate to Settings from Dashboard
1. From `/creator/dashboard`, click Settings in sidebar

**Expected:** Navigated to `/creator/settings`. Same sidebar layout. Profile section shows display_name (editable) and email (read-only). Password change section visible.

## TC-09: Update display name
1. On `/creator/settings`, change display name to "Updated Creator"
2. Submit profile form

**Expected:** Success feedback. Header nav updates to show "Updated Creator".

## TC-10: Change password
1. On `/creator/settings`, enter current password
2. Enter new password and confirm
3. Submit

**Expected:** Success feedback. Logout, then login with new password succeeds.

## TC-11: ProtectedRoute redirect
1. Log out (or clear localStorage)
2. Navigate directly to `/creator/dashboard`

**Expected:** Redirected to `/login?returnTo=%2Fcreator%2Fdashboard`. After logging in, redirected back to `/creator/dashboard`.

## TC-12: Public routes unaffected
1. Without being logged in, navigate to `/`
2. Navigate to `/techniques`
3. Navigate to `/creators`

**Expected:** All public pages load normally. No auth required. No 401 errors.

## TC-13: Logout
1. While logged in, click Logout in header nav

**Expected:** Redirected to home page. Header shows Login link instead of user name. Navigating to `/creator/dashboard` redirects to `/login`.

## TC-14: Client-side form validation on Register
1. Navigate to `/register`
2. Leave invite code empty, click Register

**Expected:** Validation error on required fields.

3. Enter mismatched passwords

**Expected:** Validation error — passwords don't match.

4. Enter password shorter than 8 characters

**Expected:** Validation error — minimum length.

## TC-15: Expired invite code
1. Create an invite code with expires_at in the past (via DB or API)
2. Attempt registration with that code

**Expected:** 403 error — "Invalid or expired invite code"

## Edge Cases
- **Expired JWT:** After 24 hours without activity, next API call should return 401 and redirect to login
- **Concurrent sessions:** Login from two browsers with same account should both work independently
- **API direct access:** `curl -X GET /api/v1/auth/me` without Authorization header returns 401
