# QR Code Gateway Setup
## Overview
The gateway registration now includes QR code generation for quick and easy Android app configuration. When a new gateway is created, the system automatically generates a QR code containing all necessary configuration data.
## What's Included in the QR Code
The QR code contains a JSON payload with:
```json
{
"api_key": "gw_live_a6e2b250dade8f6501256a8717723fc3f8ab7d4e7cb26aad470d65ee8478a82c",
"api_base_url": "http://localhost:3000",
"websocket_url": "ws://localhost:3000/cable",
"version": "1.0"
}
```
### Fields Explained
| Field | Description | Example |
|-------|-------------|---------|
| `api_key` | Gateway authentication key | `gw_live_...` (64 chars) |
| `api_base_url` | Base URL for API endpoints | `http://localhost:3000` or `https://api.example.com` |
| `websocket_url` | WebSocket connection URL | `ws://localhost:3000/cable` or `wss://api.example.com/cable` |
| `version` | Configuration format version | `1.0` |
## Features
### 1. QR Code Display
**Location**: Gateway creation success page (`/admin/gateways/:id` after creation)
**Visual Features**:
- High-quality SVG QR code
- Error correction level: High (L=H)
- White background with border
- Centered display
- Info badge explaining contents
### 2. Manual Configuration Fallback
If QR scanning is unavailable, the page also displays:
- API Base URL (with individual copy button)
- WebSocket URL (with individual copy button)
- API Key (with individual copy button)
- "Copy All" button to copy all three fields at once
### 3. Copy to Clipboard Functions
**Individual Field Copy**:
```javascript
copyField('api-base-url') // Copies just the API base URL
copyField('ws-url') // Copies just the WebSocket URL
copyField('api-key') // Copies just the API key
```
**Copy All Configuration**:
```javascript
copyAllConfig() // Copies all fields as formatted text
```
Output format:
```
API Base URL: http://localhost:3000
WebSocket URL: ws://localhost:3000/cable
API Key: gw_live_a6e2b250dade8f6501256a8717723fc3f8ab7d4e7cb26aad470d65ee8478a82c
```
## Implementation Details
### Gem Used
**rqrcode** v2.0+
- Pure Ruby QR code generator
- No external dependencies
- SVG output support
- High error correction
Added to `Gemfile`:
```ruby
gem "rqrcode", "~> 2.0"
```
### Controller Method
**File**: `app/controllers/admin/gateways_controller.rb`
```ruby
def generate_qr_code_data(api_key)
require "rqrcode"
# Determine URLs based on request
base_url = request.base_url
ws_url = request.base_url.sub(/^http/, "ws") + "/cable"
# Create JSON configuration
config_data = {
api_key: api_key,
api_base_url: base_url,
websocket_url: ws_url,
version: "1.0"
}.to_json
# Generate QR code with high error correction
qr = RQRCode::QRCode.new(config_data, level: :h)
# Return as SVG string
qr.as_svg(
offset: 0,
color: "000",
shape_rendering: "crispEdges",
module_size: 4,
standalone: true,
use_path: true
)
end
```
### View Integration
**File**: `app/views/admin/gateways/show.html.erb`
The QR code is displayed using:
```erb
<%= @qr_code_data.html_safe %>
```
## URL Detection
The system automatically detects the correct URLs based on the request:
### Development
- Base URL: `http://localhost:3000`
- WebSocket URL: `ws://localhost:3000/cable`
### Production (HTTP)
- Base URL: `http://api.example.com`
- WebSocket URL: `ws://api.example.com/cable`
### Production (HTTPS) - Recommended
- Base URL: `https://api.example.com`
- WebSocket URL: `wss://api.example.com/cable`
**Note**: WebSocket URL automatically changes from `http` to `ws` and `https` to `wss`.
## Android App Integration
### QR Code Scanning Flow
1. **User opens Android SMS Gateway app**
2. **Taps "Scan QR Code" or similar option**
3. **Camera opens with QR scanner**
4. **Scans the QR code from admin interface**
5. **App parses JSON configuration**
6. **All fields auto-populated**:
- API Base URL field
- WebSocket URL field
- API Key field
7. **User taps "Save" or "Connect"**
8. **App connects to server**
9. **Gateway appears as "Online" in admin interface**
### Expected Android App Code
The Android app should:
1. **Scan QR Code**:
```kotlin
// Using ML Kit or ZXing library
val result = qrCodeScanner.scan()
val jsonString = result.text
```
2. **Parse JSON**:
```kotlin
val config = JSONObject(jsonString)
val apiKey = config.getString("api_key")
val apiBaseUrl = config.getString("api_base_url")
val websocketUrl = config.getString("websocket_url")
val version = config.getString("version")
```
3. **Validate Version**:
```kotlin
if (version != "1.0") {
showError("Unsupported configuration version")
return
}
```
4. **Save Configuration**:
```kotlin
sharedPreferences.edit().apply {
putString("api_key", apiKey)
putString("api_base_url", apiBaseUrl)
putString("websocket_url", websocketUrl)
apply()
}
```
5. **Connect to Server**:
```kotlin
// Connect to WebSocket
webSocketClient.connect(websocketUrl, apiKey)
// Test API connection
apiClient.setBaseUrl(apiBaseUrl)
apiClient.setAuthToken(apiKey)
apiClient.sendHeartbeat()
```
## Security Considerations
### QR Code Security
✅ **Secure**:
- QR code displayed only once after creation
- Requires admin authentication to view
- Session-based display (not in URL)
- Page cannot be refreshed to see QR code again
⚠️ **Warning**:
- Anyone with camera access to the screen can scan the QR code
- QR code contains full API key in plaintext JSON
- Suitable for secure environments only
### Best Practices
1. **Display Environment**:
- Only display QR code in secure locations
- Ensure no cameras/recording devices nearby
- Clear screen after scanning
2. **Network Security**:
- Use HTTPS/WSS in production (`config.force_ssl = true`)
- Never use HTTP/WS in production
- Implement rate limiting on WebSocket connections
3. **Key Management**:
- QR code shown only once during gateway creation
- If compromised, deactivate gateway and create new one
- Regularly audit active gateways
4. **Mobile App Security**:
- Store configuration in encrypted SharedPreferences
- Use Android Keystore for API key storage
- Implement certificate pinning for API calls
- Validate SSL certificates for WebSocket connections
## Troubleshooting
### QR Code Not Displaying
**Check**:
1. `rqrcode` gem installed: `bundle show rqrcode`
2. Controller generates QR code: Check `@qr_code_data` in view
3. Browser console for JavaScript errors
4. View source - SVG should be present
**Fix**:
```bash
bundle install
bin/rails restart
```
### QR Code Too Complex to Scan
**Symptom**: QR scanner can't read the code
**Cause**: JSON payload too long (rare, but possible with very long URLs)
**Solution**:
- Use shorter domain names
- Reduce module_size in controller (current: 4)
- Lower error correction level (current: :h, try :m or :l)
### Wrong URLs in QR Code
**Symptom**: QR code contains `localhost` in production
**Cause**: `request.base_url` not detecting correctly
**Fix**: Set environment variables in production
```bash
# .env or config
RAILS_FORCE_SSL=true
RAILS_RELATIVE_URL_ROOT=https://api.example.com
```
Or override in controller:
```ruby
base_url = ENV['API_BASE_URL'] || request.base_url
```
### Android App Can't Parse QR Code
**Symptom**: App shows "Invalid QR code" error
**Causes**:
1. QR code scanner library issue
2. JSON parsing error
3. Wrong configuration version
**Debug**:
```kotlin
try {
val json = JSONObject(qrCodeText)
Log.d("QR", "API Key: ${json.getString("api_key")}")
Log.d("QR", "Base URL: ${json.getString("api_base_url")}")
Log.d("QR", "WS URL: ${json.getString("websocket_url")}")
} catch (e: Exception) {
Log.e("QR", "Parse error: ${e.message}")
}
```
## Testing
### Manual QR Code Test
1. **Create Test Gateway**:
```bash
bin/rails console
```
```ruby
gateway = Gateway.new(
device_id: "test-qr-001",
name: "QR Test Gateway",
priority: 1,
status: "offline"
)
raw_key = gateway.generate_api_key!
puts "Gateway ID: #{gateway.id}"
puts "Raw Key: #{raw_key}"
```
2. **Navigate to Success Page**:
- Visit: `http://localhost:3000/admin/gateways/new`
- Fill form and submit
- Should redirect to gateway show page with QR code
3. **Test QR Code**:
- Open QR code scanner app on phone
- Scan the displayed QR code
- Verify JSON payload contains all fields
4. **Test Copy Buttons**:
- Click individual copy buttons (API URL, WS URL, API Key)
- Verify green checkmark feedback
- Click "Copy All" button
- Paste in text editor - verify format
### Automated Test
```ruby
# test/controllers/admin/gateways_controller_test.rb
test "should generate QR code on gateway creation" do
post admin_gateways_url, params: {
gateway: {
device_id: "test-001",
name: "Test Gateway",
priority: 5
}
}
assert_response :redirect
gateway = Gateway.last
get admin_gateway_url(gateway)
assert_response :success
assert_select 'svg' # QR code should be present as SVG
end
```
## Configuration Examples
### Local Development
```json
{
"api_key": "gw_live_abc123...",
"api_base_url": "http://localhost:3000",
"websocket_url": "ws://localhost:3000/cable",
"version": "1.0"
}
```
### Staging Environment
```json
{
"api_key": "gw_live_def456...",
"api_base_url": "https://staging-api.example.com",
"websocket_url": "wss://staging-api.example.com/cable",
"version": "1.0"
}
```
### Production Environment
```json
{
"api_key": "gw_live_ghi789...",
"api_base_url": "https://api.example.com",
"websocket_url": "wss://api.example.com/cable",
"version": "1.0"
}
```
## Future Enhancements
### Possible Improvements
1. **Download QR Code**:
- Add "Download QR Code" button
- Generate PNG image
- Allow saving for later
2. **Email QR Code**:
- Send QR code via email
- Secure time-limited link
- Auto-expires after 1 hour
3. **Multiple QR Code Formats**:
- Different sizes (small, medium, large)
- Different error correction levels
- PNG, SVG, PDF options
4. **Configuration Presets**:
- Save common configurations
- Apply preset to multiple gateways
- Template system
5. **Advanced Security**:
- Encrypted QR code payload
- Time-limited configuration URLs
- Two-factor gateway activation
## Summary
✅ **Implemented**: QR code generation with all gateway configuration
✅ **Features**: Scan QR code OR manual copy/paste
✅ **Security**: One-time display, session-based, admin-only
✅ **UX**: Copy buttons with visual feedback, clear instructions
✅ **Production Ready**: Automatic URL detection (HTTP/HTTPS/WS/WSS)
The QR code feature makes gateway setup much faster and reduces configuration errors by eliminating manual typing of long API keys!