# Gas Stations Feature - Secrets Verification Guide

## Overview

Complete guide for verifying Google Maps API key secrets are correctly configured in both backend and frontend containers. This document covers verification commands, troubleshooting steps, and security validation.

## Secrets Architecture

### Backend Secret Flow

```
Host filesystem: ./secrets/app/google-maps-api-key.txt
    ↓ (Docker volume mount)
Container: /run/secrets/google-maps-api-key
    ↓ (Config loader reads at startup)
Backend service: process.env or config object
    ↓ (Used in Google Maps client)
Google Places API calls
```

### Frontend Secret Flow

```
Host filesystem: ./secrets/app/google-maps-api-key.txt
    ↓ (Docker volume mount)
Container: /run/secrets/google-maps-api-key
    ↓ (Entrypoint script reads at startup)
Generated file: /usr/share/nginx/html/config.js
    ↓ (Loaded in index.html)
Browser: window.CONFIG.googleMapsApiKey
    ↓ (Used in maps-loader.ts)
Google Maps JavaScript API
```

## Verification Commands

### 1. Host Filesystem Verification

**Check secret file exists**:
```bash
ls -la ./secrets/app/google-maps-api-key.txt
```

**Expected Output**:
```
-rw-r--r-- 1 user user 39 Jan 15 10:00 ./secrets/app/google-maps-api-key.txt
```

**View secret content** (only in development):
```bash
cat ./secrets/app/google-maps-api-key.txt
```

**Expected**: API key starting with `AIzaSy...` (39 characters)

**Check file permissions**:
```bash
stat -c "%a %n" ./secrets/app/google-maps-api-key.txt
```

**Expected**: `644` (readable by owner and group)

### 2. Backend Container Verification

**Check secret mounted in container**:
```bash
docker compose exec mvp-backend cat /run/secrets/google-maps-api-key
```

**Expected**: Same API key as host file

**Check secret file permissions in container**:
```bash
docker compose exec mvp-backend ls -la /run/secrets/google-maps-api-key
```

**Expected**: Read-only file (`:ro` mount flag)

**Check backend can access secret**:
```bash
docker compose exec mvp-backend node -e "
const fs = require('fs');
try {
  const key = fs.readFileSync('/run/secrets/google-maps-api-key', 'utf8').trim();
  console.log('Secret loaded, length:', key.length);
  console.log('Starts with AIzaSy:', key.startsWith('AIzaSy'));
} catch (error) {
  console.error('Failed to read secret:', error.message);
}
"
```

**Expected Output**:
```
Secret loaded, length: 39
Starts with AIzaSy: true
```

**Check backend logs for secret loading**:
```bash
docker compose logs mvp-backend | grep -i "google.*api.*key"
```

**Expected** (log message should NOT show actual key, only status):
```
[Config] Google Maps API key loaded successfully
```

### 3. Frontend Container Verification

**Check secret mounted in container**:
```bash
docker compose exec mvp-frontend cat /run/secrets/google-maps-api-key
```

**Expected**: Same API key as host file

**Check config.js generated**:
```bash
docker compose exec mvp-frontend cat /usr/share/nginx/html/config.js
```

**Expected Output**:
```javascript
window.CONFIG = {
  googleMapsApiKey: 'AIzaSyYourActualKeyHere'
};
```

**Check entrypoint script ran**:
```bash
docker compose logs mvp-frontend | grep -i config
```

**Expected Output**:
```
[Config] Loaded Google Maps API key from /run/secrets/google-maps-api-key
[Config] Generated /usr/share/nginx/html/config.js
```

**Check config.js is served**:
```bash
curl -s https://motovaultpro.com/config.js
```

**Expected**: JavaScript file with `window.CONFIG = {...}`

### 4. Browser Verification

**Check config loaded in browser console**:

1. Open https://motovaultpro.com in browser
2. Open Developer Tools (F12)
3. Go to Console tab
4. Run:

```javascript
console.log(window.CONFIG);
```

**Expected Output**:
```javascript
{
  googleMapsApiKey: "AIzaSyYourActualKeyHere"
}
```

**Check Google Maps script loads**:
```javascript
console.log(typeof google !== 'undefined' ? 'Google Maps loaded' : 'Not loaded yet');
```

**Check for config errors**:
```javascript
// Should not show any errors related to config
console.log(document.querySelectorAll('script[src*="config.js"]').length);
// Should return: 1
```

### 5. API Integration Verification

**Test backend can call Google Maps API**:
```bash
docker compose exec mvp-backend node -e "
const https = require('https');
const fs = require('fs');

const apiKey = fs.readFileSync('/run/secrets/google-maps-api-key', 'utf8').trim();
const url = \`https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=37.7749,-122.4194&radius=5000&type=gas_station&key=\${apiKey}\`;

https.get(url, (res) => {
  let data = '';
  res.on('data', (chunk) => data += chunk);
  res.on('end', () => {
    const json = JSON.parse(data);
    console.log('API Status:', json.status);
    console.log('Results:', json.results?.length || 0, 'stations');
  });
}).on('error', (err) => {
  console.error('API Error:', err.message);
});
"
```

**Expected Output**:
```
API Status: OK
Results: 20 stations
```

**Test full API workflow with JWT**:
```bash
# Get JWT token (from Auth0 or test token)
export TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

# Search for stations
curl -X POST https://motovaultpro.com/api/stations/search \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": 37.7749,
    "longitude": -122.4194,
    "radius": 5000
  }' | jq '.stations | length'
```

**Expected**: Number greater than 0 (indicating stations found)

## Security Validation

### 1. Secret Not in Environment Variables

**Check backend environment**:
```bash
docker compose exec mvp-backend env | grep -i google
```

**Expected**: No GOOGLE_MAPS_API_KEY in environment (should use file mount)

**Check frontend environment**:
```bash
docker compose exec mvp-frontend env | grep -i google
```

**Expected**: No GOOGLE_MAPS_API_KEY in environment

### 2. Secret Not in Docker Images

**Check backend image**:
```bash
docker history motovaultpro-backend | grep -i google
```

**Expected**: No API key in image layers

**Check frontend image**:
```bash
docker history motovaultpro-frontend | grep -i google
```

**Expected**: No API key in image layers

### 3. Secret Not in Logs

**Check all logs for API key exposure**:
```bash
docker compose logs | grep -i "AIzaSy"
```

**Expected**: No matches (API key should never be logged)

**Check for "secret" or "key" logging**:
```bash
docker compose logs | grep -i "api.*key" | grep -v "loaded successfully"
```

**Expected**: Only status messages, no actual key values

### 4. File Permissions Secure

**Check host file not world-readable**:
```bash
ls -l ./secrets/app/google-maps-api-key.txt | awk '{print $1}'
```

**Expected**: `-rw-r--r--` or stricter (not `-rw-rw-rw-`)

**Check container mount is read-only**:
```bash
docker compose config | grep -A5 "google-maps-api-key"
```

**Expected**: Contains `:ro` flag

### 5. Secret Rotation Test

**Update secret and verify change propagates**:

```bash
# Backup current secret
cp ./secrets/app/google-maps-api-key.txt ./secrets/app/google-maps-api-key.txt.bak

# Update with new key (test key for rotation testing)
echo "AIzaSyTestKeyForRotation" > ./secrets/app/google-maps-api-key.txt

# Restart containers
docker compose restart mvp-backend mvp-frontend

# Wait for startup
sleep 5

# Verify new key loaded in backend
docker compose exec mvp-backend cat /run/secrets/google-maps-api-key

# Verify new key in frontend config.js
docker compose exec mvp-frontend cat /usr/share/nginx/html/config.js

# Restore original key
mv ./secrets/app/google-maps-api-key.txt.bak ./secrets/app/google-maps-api-key.txt

# Restart again
docker compose restart mvp-backend mvp-frontend
```

## Troubleshooting

### Backend Can't Read Secret

**Symptom**:
```bash
docker compose logs mvp-backend | grep -i "google"
# Shows: Failed to load Google Maps API key
```

**Solutions**:

1. **Check file exists on host**:
   ```bash
   ls -la ./secrets/app/google-maps-api-key.txt
   ```

2. **Check docker-compose.yml mount**:
   ```bash
   grep -A5 "mvp-backend:" docker-compose.yml | grep google-maps
   ```
   Should show:
   ```yaml
   - ./secrets/app/google-maps-api-key.txt:/run/secrets/google-maps-api-key:ro
   ```

3. **Check file in container**:
   ```bash
   docker compose exec mvp-backend ls -la /run/secrets/
   ```

4. **Restart backend**:
   ```bash
   docker compose restart mvp-backend
   ```

### Frontend config.js Not Generated

**Symptom**:
```bash
docker compose exec mvp-frontend cat /usr/share/nginx/html/config.js
# Shows: No such file or directory
```

**Solutions**:

1. **Check entrypoint script exists**:
   ```bash
   docker compose exec mvp-frontend ls -la /app/load-config.sh
   ```

2. **Check entrypoint runs**:
   ```bash
   docker compose logs mvp-frontend | head -20
   ```
   Should show config generation messages.

3. **Run entrypoint manually**:
   ```bash
   docker compose exec mvp-frontend sh /app/load-config.sh
   ```

4. **Restart frontend**:
   ```bash
   docker compose restart mvp-frontend
   ```

### Browser Shows "API key undefined"

**Symptom**: Browser console shows `window.CONFIG.googleMapsApiKey` is undefined

**Solutions**:

1. **Check config.js loads**:
   Open browser DevTools > Network tab > Refresh page > Look for `config.js`

2. **Check config.js content**:
   ```bash
   curl https://motovaultpro.com/config.js
   ```

3. **Check index.html loads config.js**:
   View page source, look for:
   ```html
   <script src="/config.js"></script>
   ```

4. **Clear browser cache**:
   Hard refresh: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac)

### Google API Returns "Invalid API Key"

**Symptom**: API calls return 400 error with "The provided API key is invalid"

**Solutions**:

1. **Verify key format**:
   ```bash
   cat ./secrets/app/google-maps-api-key.txt | wc -c
   ```
   Should be 39 characters (including newline) or 40.

2. **Check for extra whitespace**:
   ```bash
   cat ./secrets/app/google-maps-api-key.txt | od -c
   ```
   Should only show key and newline, no spaces/tabs.

3. **Verify key in Google Cloud Console**:
   - Go to APIs & Services > Credentials
   - Confirm key exists and is not deleted

4. **Check API restrictions**:
   - Verify IP/domain restrictions don't block your server
   - Verify API restrictions include Places API

### Secret File Permissions Wrong

**Symptom**: Container can't read secret file

**Solutions**:

```bash
# Fix file permissions
chmod 644 ./secrets/app/google-maps-api-key.txt

# Verify ownership
ls -l ./secrets/app/google-maps-api-key.txt

# Restart containers
docker compose restart mvp-backend mvp-frontend
```

## Automated Verification Script

Create a verification script for convenience:

```bash
#!/bin/bash
# verify-secrets.sh

echo "=== Gas Stations Secrets Verification ==="
echo ""

echo "1. Host file exists:"
[ -f ./secrets/app/google-maps-api-key.txt ] && echo "✓ PASS" || echo "✗ FAIL"

echo ""
echo "2. Backend can read secret:"
docker compose exec -T mvp-backend cat /run/secrets/google-maps-api-key >/dev/null 2>&1 && echo "✓ PASS" || echo "✗ FAIL"

echo ""
echo "3. Frontend can read secret:"
docker compose exec -T mvp-frontend cat /run/secrets/google-maps-api-key >/dev/null 2>&1 && echo "✓ PASS" || echo "✗ FAIL"

echo ""
echo "4. Frontend config.js generated:"
docker compose exec -T mvp-frontend cat /usr/share/nginx/html/config.js >/dev/null 2>&1 && echo "✓ PASS" || echo "✗ FAIL"

echo ""
echo "5. API key format valid:"
KEY=$(cat ./secrets/app/google-maps-api-key.txt)
[[ $KEY =~ ^AIzaSy ]] && echo "✓ PASS" || echo "✗ FAIL"

echo ""
echo "=== Verification Complete ==="
```

**Usage**:
```bash
chmod +x verify-secrets.sh
./verify-secrets.sh
```

## References

- Architecture: `/backend/src/features/stations/docs/ARCHITECTURE.md`
- Google Maps Setup: `/backend/src/features/stations/docs/GOOGLE-MAPS-SETUP.md`
- Deployment Checklist: `/backend/src/features/stations/docs/deployment/DEPLOYMENT-CHECKLIST.md`
- Runtime Config: `/frontend/docs/RUNTIME-CONFIG.md`
