# Token Persistence Guide

## Overview

The Kosmi bridge now caches JWT authentication tokens to avoid repeated browser automation on every startup. The token is stored in a local directory that persists across Docker container rebuilds and restarts.

## How It Works

### Token Cache Location

The token cache is stored in a file called `kosmi_token_cache.json` in the following locations:

- **Docker (Production)**: `./data/kosmi_token_cache.json` (mounted from your host machine)
- **Local Development**: `~/.matterbridge/kosmi_token_cache.json`

### Token Cache Structure

The cache file contains:

```json
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "email": "your-email@example.com",
  "expires_at": "2026-11-02T15:56:23Z",
  "saved_at": "2025-11-02T15:56:23Z"
}
```

### Token Lifecycle

1. **On Startup**: The bridge checks for a cached token
   - If found and valid, it uses the cached token (no browser automation needed)
   - If expired or expiring within 7 days, it performs fresh authentication
   - If not found, it performs fresh authentication

2. **Token Expiry**: Kosmi JWT tokens expire after 1 year
   - The bridge automatically refreshes tokens that expire within 7 days
   - You'll see a log message indicating how long until the token expires

3. **Token Storage**: After successful authentication, the token is saved to the cache file
   - File permissions are set to `0600` (read/write for owner only)
   - The cache directory is created automatically if it doesn't exist

## Docker Configuration

### Volume Mount

The `docker-compose.yml` includes a volume mount for persistent storage:

```yaml
volumes:
  - ./data:/app/data:z
```

This mounts the `./data` directory from your host machine into the container at `/app/data`.

### Environment Variable

The container sets the `MATTERBRIDGE_DATA_DIR` environment variable:

```yaml
environment:
  - MATTERBRIDGE_DATA_DIR=/app/data
```

This tells the bridge where to store persistent data like the token cache.

## Usage

### First Run

On the first run with email/password configured:

1. The bridge will launch a headless browser
2. Authenticate with Kosmi using your credentials
3. Extract and cache the JWT token
4. Save it to `./data/kosmi_token_cache.json`

You'll see logs like:

```
level=info msg="No cached token found, performing authentication..."
level=info msg="Starting browser automation for authentication..."
level=info msg="💾 Token cached (expires in 8760h)"
```

### Subsequent Runs

On subsequent runs (container restarts, rebuilds, etc.):

1. The bridge checks the cached token
2. If valid, uses it immediately (no browser needed)
3. Connects to Kosmi in seconds

You'll see logs like:

```
level=info msg="✅ Using cached token (expires in 8736h)"
```

### Token Refresh

When the token is close to expiring (within 7 days):

1. The bridge automatically performs fresh authentication
2. Updates the cached token
3. Continues normal operation

You'll see logs like:

```
level=info msg="Cached token expires soon (2025-11-09T15:56:23Z), will refresh"
level=info msg="Starting browser automation for authentication..."
level=info msg="💾 Token cached (expires in 8760h)"
```

## File Structure

After running with authentication, your directory structure will look like:

```
irc-kosmi-relay/
├── data/                              # Persistent data directory
│   └── kosmi_token_cache.json        # Cached JWT token
├── docker-compose.yml
├── matterbridge.toml
└── ...
```

## Troubleshooting

### Token Cache Not Persisting

If the token cache doesn't persist across container restarts:

1. Check that the `./data` directory exists and is writable
2. Verify the volume mount in `docker-compose.yml` is correct
3. Check container logs for permission errors

### Force Token Refresh

To force a fresh authentication (e.g., if credentials changed):

```bash
# Stop the container
docker-compose down

# Remove the cached token
rm ./data/kosmi_token_cache.json

# Start the container
docker-compose up -d
```

### Check Token Status

To view the current cached token:

```bash
cat ./data/kosmi_token_cache.json | jq .
```

This will show you:
- When the token was saved
- When it expires
- Which email it's associated with

## Security Notes

- The token cache file has restricted permissions (`0600`) for security
- The token is a JWT that expires after 1 year
- The cache file is stored locally and never transmitted
- If you commit your code to version control, add `data/` to `.gitignore`

## Benefits

1. **Faster Startup**: No browser automation on every restart (saves 10-15 seconds)
2. **Reduced Resource Usage**: No need to launch Chromium on every startup
3. **Persistence**: Token survives container rebuilds, restarts, and host reboots
4. **Automatic Refresh**: Token is automatically refreshed before expiry
5. **Local Storage**: Token is stored on your host machine, not in the container
