# Authentication Issue - Bot Appears as Anonymous

## Problem

The bot successfully authenticates via browser automation and joins the Kosmi room, but appears in the user list as an **anonymous user** (e.g., "Anonymous Donkey") instead of as the authenticated account.

## What We Know

### ✅ Working Correctly

1. **Browser authentication**: Successfully logs in and obtains JWT token
2. **Token format**: Valid JWT with correct structure and claims
3. **Token transmission**: Correct token is sent in `connection_init`
4. **Server acceptance**: Server accepts the token (returns `connection_ack`)
5. **Room joining**: Successfully joins the room (`joinRoom` mutation returns `ok: true`)

### 🔍 Investigation Results

#### Token Claims Analysis

The authenticated JWT token contains:
```json
{
  "aud": "kosmi",
  "exp": 1761874131,
  "iat": 1730338131,
  "iss": "kosmi",
  "sub": "e410acc0-e4bd-4694-8498-f20b9aa033fc",
  "typ": "access"
}
```

**Key finding**: The token **only contains the user ID** (`sub`), but **NO display name, username, or email**. This is just an authentication token, not a profile token.

#### GraphQL API Queries

Tested the following queries with the authenticated token:
- `query { me { ... } }` - ❌ Field doesn't exist
- `query { currentUser { ... } }` - ❌ Field doesn't exist
- `query { user { ... } }` - ❌ Field doesn't exist
- `query { viewer { ... } }` - ❌ Field doesn't exist

**Conclusion**: There's no GraphQL query to fetch the current user's profile.

#### WebSocket Flow

Current flow:
1. `connection_init` with authenticated token → Server accepts
2. `connection_ack` → Server acknowledges
3. Subscribe to `newMessage` → Working
4. `joinRoom` mutation → Returns `ok: true`
5. Bot appears in user list as "Anonymous [Animal]"

## Hypotheses

### 1. Missing Profile Fetch
The server might need a separate API call (REST or GraphQL) to fetch the user profile using the user ID from the token.

### 2. Missing Display Name Mutation
There might be a GraphQL mutation to set the display name after joining:
- `mutation { setDisplayName(name: "...") }`
- `mutation { updateProfile(displayName: "...") }`

### 3. Server-Side Bug
The server might not be correctly associating the authenticated token with the user profile when joining via WebSocket.

### 4. Additional WebSocket Message
The browser might be sending an additional WebSocket message after `joinRoom` that we're not aware of.

## Next Steps

1. **Check `connection_ack` payload**: See if the server returns user info
2. **Monitor browser WebSocket traffic**: Watch what messages the browser sends after successful login and room join
3. **Test GraphQL introspection**: Query the schema to see all available mutations
4. **Compare anonymous vs authenticated flow**: See if there are any differences in the WebSocket message sequence

## Logs

### Successful Authentication and Join
```
time="2025-11-01T14:48:51-04:00" level=info msg="✅ Successfully obtained token via browser automation" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="   Email used: d2bkvqnh0@mozmail.com" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="   Token (first 50 chars): eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJrb..." prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="   Token user ID (sub): e410acc0-e4bd-4694-8498-f20b9aa033fc" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="   Token type (typ): access" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="✓ getToken: Using manually provided token" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="  Length: 371" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="  First 50: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJrb..." prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="Sending connection_init with token (length: 371, first 20 chars: eyJhbGciOiJIUzUxMiIs...)" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="✅ WebSocket connection established and authenticated" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="✅ Successfully joined room" prefix=kosmi
time="2025-11-01T14:48:51-04:00" level=info msg="Join response payload: {"data":{"joinRoom":{"ok":true}}}" prefix=kosmi
```

**Result**: Bot appears as "Anonymous [Animal]" in the user list despite successful authentication.

## Files Modified for Debugging

- `bridge/kosmi/browser_auth.go`: Added comprehensive token logging
- `bridge/kosmi/kosmi.go`: Added token setting confirmation
- `bridge/kosmi/graphql_ws_client.go`: Added token source and `connection_ack` payload logging
- `cmd/decode-token/main.go`: Tool to decode and analyze JWT tokens
- `cmd/test-profile-query/main.go`: Tool to test GraphQL profile queries

