# Technical Specification: Add Environment Variable Support for Firebase Authentication

## Task Complexity: Medium

**Rationale**: The authentication system already exists with web-based Firebase Auth. This task adds environment variable support as an alternative token storage mechanism while maintaining backward compatibility with the existing keychain storage. Requires careful handling of precedence, fallback behavior, and multiple file modifications.

---

## Technical Context

### Current Architecture

**Language**: JavaScript (Node.js)  
**Package Manager**: npm  
**Key Dependencies**:
- `keytar` - System keychain storage for tokens
- `axios` - HTTP client for API requests
- `inquirer` - Interactive CLI prompts
- `commander` - CLI framework
- `chalk` - Terminal styling
- `open` - Browser launching

### Existing Authentication System

The CLI currently supports three authentication methods:

1. **OAuth Flow (Auth0)** - Opens browser for OAuth authentication
2. **Firebase Email/Password** - Direct Firebase Auth REST API
3. **Manual Token Entry** - User pastes token directly

**Token Storage**: Tokens are stored securely in the system keychain via `keytar`:
- Service Name: `bild-cli`
- Account Name: `bildit-cms-token`

**Token Usage**: Bearer token in `Authorization` headers for:
- CMS API calls (`/api/apps`, `/api/codelibs`, etc.)
- Firebase Realtime Database REST API calls (for versions)

---

## Requirements

### Functional Requirements

1. **Environment Variable Support**
   - Support `BILD_FIREBASE_TOKEN` environment variable for token storage
   - Support `FIREBASE_TOKEN` as an alias (common convention)
   - ENV var tokens take precedence over keychain-stored tokens
   - Maintain backward compatibility with keychain storage

2. **Token Retrieval Precedence**
   ```
   1. BILD_FIREBASE_TOKEN environment variable
   2. FIREBASE_TOKEN environment variable
   3. Keychain-stored token (existing behavior)
   4. Error: Not authenticated
   ```

3. **Token Storage Options**
   - Continue storing to keychain by default after login
   - Optionally export token as ENV var command
   - Add `--env` flag to login command to display token for manual export

4. **New Commands**
   - `bild token` - Display current token (for ENV var export)
   - `bild token --export` - Display shell-specific export command

5. **Enhanced Login Flow**
   - Add `--env` flag to show token after authentication
   - Provide instructions for exporting to ENV var
   - Support both keychain and ENV var workflows

### Non-Functional Requirements

1. **Security**
   - Warn users about ENV var token exposure risks
   - Don't automatically write tokens to shell config files
   - Validate token format before accepting from ENV

2. **Backward Compatibility**
   - Existing keychain behavior unchanged by default
   - All existing commands continue to work
   - No breaking changes to CLI interface

3. **User Experience**
   - Clear instructions for ENV var usage
   - Helpful error messages when token is invalid/expired
   - Support for CI/CD environments (non-interactive)

---

## Implementation Approach

### File Modifications

#### 1. **src/lib/auth.js** (Major Changes)
- Modify `getToken()` to check ENV vars first
- Add `getTokenSource()` to identify token source
- Add token validation helper
- Add functions:
  - `getTokenFromEnv()` - Check BILD_FIREBASE_TOKEN and FIREBASE_TOKEN
  - `validateToken(token)` - Basic JWT format validation
  - `displayToken()` - Show current token for export

#### 2. **src/commands/login.js** (Minor Changes)
- Add `--env` flag to display token after authentication
- Show ENV var export instructions when `--env` used
- Provide shell-specific export commands (bash, zsh, fish, powershell)

#### 3. **src/commands/token.js** (New File)
- New command to display current token
- `--export` flag for shell-specific export syntax
- `--validate` flag to check if token is valid
- Auto-detect shell type for export syntax

#### 4. **src/index.js** (Minor Changes)
- Register new `token` command
- Update help text with ENV var documentation

#### 5. **src/lib/api.js** (Minor Changes)
- Enhanced error messages mentioning ENV var option
- Better handling of 401 authentication errors

#### 6. **Documentation Updates** (Out of scope per rules, but noted)
- README.md would need updates (user must request)

### Token Validation

Implement basic JWT validation:
```javascript
function validateToken(token) {
  if (!token || typeof token !== 'string') return false
  // JWT tokens have 3 parts separated by dots
  const parts = token.split('.')
  if (parts.length !== 3) return false
  // JWT typically starts with 'eyJ' (base64 of '{"')
  if (!token.startsWith('eyJ')) return false
  return true
}
```

### ENV Variable Names

**Primary**: `BILD_FIREBASE_TOKEN` (CLI-specific, prevents conflicts)  
**Alias**: `FIREBASE_TOKEN` (common convention, wider compatibility)

### Example Usage Scenarios

#### Scenario 1: CI/CD Environment
```bash
export BILD_FIREBASE_TOKEN="eyJhbGciOi..."
bild library add component.jsx --app-id myapp
```

#### Scenario 2: Get Token for Export
```bash
bild login https://cms.example.com
bild token --export
# Output: export BILD_FIREBASE_TOKEN="eyJhbGciOi..."
```

#### Scenario 3: Login with ENV Display
```bash
bild login https://cms.example.com --env
# Authenticates and displays export command
```

#### Scenario 4: Validate Current Token
```bash
export BILD_FIREBASE_TOKEN="..."
bild token --validate
# Output: ✓ Valid token from environment variable (BILD_FIREBASE_TOKEN)
```

---

## Data Model Changes

**No database/API changes required**

Configuration file (`~/.bild.json`) - No schema changes needed

---

## Interface Changes

### New Command: `bild token`

```
bild token [options]

Display and manage authentication token

Options:
  --export        Show shell-specific export command
  --validate      Check if current token is valid
  --source        Show token source (env, keychain, none)
  -h, --help      Display help for command

Examples:
  $ bild token                    # Display current token
  $ bild token --export           # Show export command
  $ bild token --validate         # Validate current token
  $ bild token --source           # Show where token comes from
```

### Modified Command: `bild login`

Add new option:
```
--env           Display token after authentication for ENV export
```

---

## Error Handling

### New Error Scenarios

1. **Invalid ENV Token**
   ```
   Error: Invalid token format in BILD_FIREBASE_TOKEN
   Token should be a JWT starting with 'eyJ'
   Run: bild login <url>
   ```

2. **Expired ENV Token**
   ```
   Error: Authentication failed (401)
   Token from BILD_FIREBASE_TOKEN may be expired
   Run: bild login <url> to get a new token
   ```

3. **No Token Available**
   ```
   Error: No authentication token found
   
   Options:
   1. Login: bild login <url>
   2. Set ENV var: export BILD_FIREBASE_TOKEN="your-token"
   3. Use manual token: bild login <url> --token
   ```

---

## Verification Approach

### Manual Testing Steps

1. **Test ENV var precedence**
   - Login with keychain storage
   - Set BILD_FIREBASE_TOKEN with different token
   - Verify ENV token is used

2. **Test token command**
   - `bild token` displays current token
   - `bild token --export` shows correct shell syntax
   - `bild token --validate` correctly validates token
   - `bild token --source` shows correct source

3. **Test login --env flag**
   - `bild login <url> --env` shows export instructions
   - Token is still saved to keychain
   - Export command works in shell

4. **Test CI/CD workflow**
   - Set BILD_FIREBASE_TOKEN in environment
   - Run commands without keychain access
   - Verify all commands work

5. **Test invalid tokens**
   - Set invalid token in ENV
   - Verify error messages are helpful
   - Verify fallback behavior

6. **Test backward compatibility**
   - Ensure existing keychain-only workflow unchanged
   - All existing commands work without ENV vars

### Lint and Build Commands

```bash
npm run lint      # Run ESLint on all modified files
npm run lint:fix  # Auto-fix ESLint issues
```

**Note**: No test suite currently exists in the project (package.json shows `test: "echo \"Error: no test specified\" && exit 1"`)

---

## Security Considerations

1. **ENV Variable Exposure**
   - Warn users that ENV vars are visible to all processes
   - Recommend keychain for local development
   - ENV vars suitable for CI/CD or containerized environments

2. **Token Display**
   - Mask token in error messages by default
   - Only show full token in `bild token` command (intentional)
   - Never log tokens to files

3. **Token Validation**
   - Basic format validation only (structural check)
   - Actual authentication verification done by Firebase/CMS backend
   - Don't decode/inspect token contents in CLI

4. **Shell History**
   - Warn about `export` commands in shell history
   - Recommend using shell config files with restricted permissions
   - Suggest tools like `pass` or `1password` for automation

---

## Edge Cases

1. **Both ENV vars set**: `BILD_FIREBASE_TOKEN` takes precedence over `FIREBASE_TOKEN`
2. **Empty ENV var**: Treated as not set, fall back to keychain
3. **Whitespace in token**: Trim whitespace automatically
4. **Token with "Bearer " prefix**: Strip prefix automatically
5. **Shell detection failure**: Default to bash/zsh syntax for export
6. **No keychain access**: ENV var becomes primary method (already a fallback)

---

## Future Enhancements (Out of Scope)

- Token refresh mechanism
- Multiple profile support (different CMS instances)
- Token encryption at rest
- Integration with secret management tools (Vault, AWS Secrets Manager)
- Automatic token expiration detection

---

## Dependencies

**No new dependencies required** - All functionality can be implemented with existing packages.

---

## Rollout Plan

1. Implement changes in feature branch
2. Test locally with various scenarios
3. Run linter on modified files
4. Manual verification of all test scenarios
5. Update plan.md with completion status
6. Ready for merge (user decision)

---

## Breaking Changes

**None** - This is a fully backward-compatible enhancement.
