# JWT Authentication Testing Guide

## Local Testing (Release Mode)

### Prerequisites
- .NET 10 SDK
- PostgreSQL SSH tunnel
- curl or Postman

### Step 1: Start SSH Tunnel

```powershell
ssh -L 5432:127.0.0.1:5432 kjh2064@178.104.200.7
```

Keep this terminal open.

### Step 2: Start Backend (Release Mode)

```powershell
cd D:\JobRoomz\KArtSell.Aegis

# Set test JWT key (32 bytes = 256 bits)
$env:JWT_KEY = "test-key-32-bytes-min-for-hs256!!"

# Set PostgreSQL connection
$env:KARTSELL_POSTGRES = "Host=127.0.0.1;Port=5432;Database=kartselldb;Username=kartsell;Password=kartsell4321@!"

# Run Release mode
dotnet run -c Release --project src/KArtSell.Host

# Expected output:
# Now listening on: http://0.0.0.0:5002
```

Wait for "Application started" message.

### Step 3: Start Frontend Dev Server

```powershell
cd D:\JobRoomz\KArtSell.Aegis\frontend
pnpm dev

# Expected output:
# VITE v... ready in ... ms
# ➜  Local:   http://localhost:5174/
```

### Step 4: Test Login Flow

#### Option A: Browser (Recommended)

1. Open http://localhost:5174
2. Should redirect to `/login` (no auth token)
3. Enter credentials:
   - Username: `testuser`
   - Password: `testpass`
4. Click "Sign In"
5. Should receive JWT token and redirect to `/home`
6. Check browser DevTools > Application > localStorage
   - `kartsell_auth_token`: Contains JWT token
   - `kartsell_expires_at`: Unix timestamp (current time + 1 hour)

#### Option B: curl (API Testing)

**1. Login Request**
```bash
curl -X POST http://localhost:5002/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"testuser","password":"testpass","role":"Admin"}'
```

**Expected Response:**
```json
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresIn": 3600,
  "tokenType": "Bearer"
}
```

**2. Extract Token**
```bash
# Copy accessToken value
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```

**3. Use Token in Protected Endpoint**
```bash
curl http://localhost:5002/api/identities \
  -H "Authorization: Bearer $TOKEN"
```

**Expected:** Success (200 OK) or relevant business response

**4. Test Expired/Invalid Token**
```bash
# Invalid token
curl http://localhost:5002/api/identities \
  -H "Authorization: Bearer invalid.token.here"

# Expected: 401 Unauthorized
```

## Test Scenarios

### Scenario 1: Successful Login
✅ User provides correct credentials
✅ Backend returns JWT token
✅ Frontend stores token in localStorage
✅ Subsequent requests include Authorization header
✅ User can access protected resources

### Scenario 2: Invalid Credentials
❌ User provides wrong password
✅ Backend returns 401 Unauthorized
✅ Frontend shows error message
✅ No token stored
✅ User remains on login page

### Scenario 3: Token Expiration
✅ Token is valid initially
⏳ Wait for token expiration (or manually adjust `kartsell_expires_at`)
✅ Frontend detects expiration
✅ Protected endpoint returns 401
✅ Frontend automatically logs out
✅ User redirected to login

### Scenario 4: API Interceptor
✅ User logs in and receives token
✅ Make request via fetch API
✅ setupAuthInterceptor adds Authorization header
✅ Backend receives and validates token
✅ Request succeeds with 200 OK

### Scenario 5: Multiple Tabs/Windows
✅ Login in Tab 1
✅ Token stored in localStorage
✅ Open Tab 2 to same app
✅ Tab 2 automatically has token (from localStorage)
✅ Both tabs can make authenticated requests

## Debugging

### Check Backend JWT Configuration

```bash
# Add this to Program.cs temporarily for debugging
Console.WriteLine($"JWT Key: {config["Jwt:Key"]}");
Console.WriteLine($"JWT Issuer: {config["Jwt:Issuer"]}");
Console.WriteLine($"JWT Audience: {config["Jwt:Audience"]}");
```

### Check Frontend Token

```javascript
// Open browser console
localStorage.getItem('kartsell_auth_token')
localStorage.getItem('kartsell_expires_at')
new Date(parseInt(localStorage.getItem('kartsell_expires_at')))
```

### Enable Debug Logging

**Backend:**
```json
{
  "Serilog": {
    "MinimumLevel": "Debug"
  }
}
```

**Frontend:**
```typescript
// In useAuthApi.ts
console.log('Auth state:', authState.value)
console.log('Token valid:', getToken())
```

### Network Inspector

1. Open browser DevTools > Network tab
2. Click "Sign In"
3. Look for `POST /api/auth/login`
4. Check response has `accessToken`
5. Make subsequent API request
6. Check request headers include `Authorization: Bearer ...`

## Common Issues & Solutions

### Issue: 401 Unauthorized on Protected Endpoints

**Possible Causes:**
1. Token not included in Authorization header
   - Check setupAuthInterceptor in main.ts
   - Verify localStorage token exists

2. Token expired
   - Check `kartsell_expires_at` in localStorage
   - Set `Jwt:ExpirationMinutes` to larger value for testing

3. JWT key mismatch
   - Backend JWT key must match production key
   - Ensure `JWT_KEY` environment variable is set

4. Token signature invalid
   - Check JWT signature on jwt.io
   - Verify HMAC SHA256 algorithm

**Solution:**
```bash
# 1. Check token value
localStorage.getItem('kartsell_auth_token')

# 2. Decode token (jwt.io)
# Copy token to https://jwt.io

# 3. Verify claims
# Should have: NameIdentifier, Name, Role, auth_mode

# 4. Check expiration
new Date(parseInt(localStorage.getItem('kartsell_expires_at')))
```

### Issue: Redirect Loop

**Possible Causes:**
1. Token always invalid
2. setupAuthInterceptor not working
3. Router guard issue

**Solution:**
```bash
# Check LocalStorage
localStorage.clear()

# Restart frontend
# Re-login

# Check Network tab for actual requests
```

### Issue: CORS Errors

**Backend and Frontend on Different Ports**
- Backend: http://localhost:5002
- Frontend: http://localhost:5174

**Solution:**
Add CORS middleware to backend:
```csharp
// In Program.cs
app.UseCors(builder => builder
    .AllowAnyOrigin()
    .AllowAnyMethod()
    .AllowAnyHeader());
```

## Performance Testing

### Load Test JWT Validation

```powershell
# Generate 100 requests with valid token
$token = "eyJ..." # from login response

1..100 | ForEach-Object {
    curl http://localhost:5002/api/identities `
      -H "Authorization: Bearer $token" `
      -w "%{http_code}\n"
}
```

Expected: All 200 or 401 (consistent)

### Token Generation Performance

```bash
time (for i in {1..10}; do
  curl -X POST http://localhost:5002/api/auth/login \
    -H "Content-Type: application/json" \
    -d '{"username":"test","password":"test"}' \
    > /dev/null
done)
```

Expected: < 500ms per request

## Cleanup

After testing:

```powershell
# Kill backend
Ctrl+C in backend terminal

# Kill frontend
Ctrl+C in frontend terminal

# Clear test data
localStorage.clear()

# Close SSH tunnel
Ctrl+C in SSH terminal
```

## Next Steps

If all tests pass:
1. ✅ JWT authentication working in Release mode
2. → Proceed to **Phase 2: Production Deployment Preparation**
3. → Implement database credential validation
4. → Configure production JWT key
