Remove tests files
This commit is contained in:
-135
@@ -1,135 +0,0 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to Amnezia VPN Web Panel will be documented in this file.
|
||||
|
||||
## [1.1.0] - 2025-11-06
|
||||
|
||||
### Added
|
||||
- **Traffic Statistics Tracking**
|
||||
- Real-time bandwidth monitoring (upload/download)
|
||||
- Last handshake tracking
|
||||
- Online/offline status detection
|
||||
- Formatted stats display (B, KB, MB, GB, TB)
|
||||
- Manual sync stats button on server and client pages
|
||||
- Batch stats sync for all clients on server
|
||||
|
||||
- **Client Access Control**
|
||||
- Revoke client access (temporary disable)
|
||||
- Restore revoked clients
|
||||
- Improved delete with proper cleanup
|
||||
- Status badges (Active/Disabled)
|
||||
|
||||
- **Enhanced UI**
|
||||
- Traffic columns in client list table
|
||||
- Last seen timestamp display
|
||||
- Revoke/Restore/Delete action buttons
|
||||
- Real-time stats refresh (AJAX)
|
||||
- Online status indicator (green dot)
|
||||
- Improved client view page with stats panel
|
||||
|
||||
- **API Endpoints**
|
||||
- `GET /api/clients/{id}` - Get client with stats
|
||||
- `POST /api/clients/{id}/revoke` - Revoke client access
|
||||
- `POST /api/clients/{id}/restore` - Restore client access
|
||||
- `GET /api/servers/{id}/clients` - Get all clients with stats
|
||||
- `POST /servers/{id}/sync-stats` - Batch sync server clients
|
||||
- `POST /clients/{id}/sync-stats` - Sync single client stats
|
||||
|
||||
### Technical
|
||||
- Database migration `002_add_traffic_stats.sql`
|
||||
- New columns: `bytes_sent`, `bytes_received`, `last_handshake`, `last_sync_at`
|
||||
- WireGuard stats parsing from `wg show` output
|
||||
- Peer removal from wg0.conf using sed
|
||||
- `wg syncconf` for live config updates
|
||||
|
||||
### Documentation
|
||||
- Created `TRAFFIC_STATS.md` - Complete traffic stats guide
|
||||
- API usage examples
|
||||
- Troubleshooting section
|
||||
|
||||
## [1.0.0] - 2024-11-05
|
||||
|
||||
### Added
|
||||
- Initial release of Amnezia VPN Web Management Panel
|
||||
- Full VPN server deployment via SSH
|
||||
- AmneziaWG container management on remote servers
|
||||
- Client configuration creation and management
|
||||
- QR code generation compatible with Amnezia VPN apps
|
||||
- User authentication system (login/register/logout)
|
||||
- Role-based access control (admin/user)
|
||||
- Modern responsive UI with Tailwind CSS
|
||||
- Dashboard with server and client overview
|
||||
- Server CRUD operations (Create, Read, Update, Delete)
|
||||
- Client management with download and QR code features
|
||||
- Docker Compose deployment setup
|
||||
- Database migrations system
|
||||
- Twig template engine integration
|
||||
- REST API foundation for future Telegram bot integration
|
||||
|
||||
### Technical Details
|
||||
- PHP 8.2 backend
|
||||
- MySQL 8.0 database
|
||||
- Endroid QR Code library v5.x integration
|
||||
- Qt/QDataStream compatible QR encoding (tested with Amnezia apps)
|
||||
- AWG obfuscation parameters support (Jc, Jmin, Jmax, S1, S2, H1-H4)
|
||||
- Secure password hashing with bcrypt
|
||||
- PDO prepared statements for SQL injection prevention
|
||||
- XSS protection via Twig auto-escaping
|
||||
|
||||
### Security
|
||||
- Default admin account: admin@amnez.ia / admin123 (change immediately!)
|
||||
- Bcrypt password hashing
|
||||
- SQL injection prevention
|
||||
- XSS protection
|
||||
- Session-based authentication
|
||||
|
||||
### Known Issues
|
||||
- QR code library updated to v5.x with API compatibility fixes
|
||||
- Server deletion not yet removing Docker containers from remote servers
|
||||
- Client deletion not yet updating server wg0.conf file
|
||||
- API authentication (JWT) not yet implemented
|
||||
- Rate limiting not yet implemented
|
||||
|
||||
### Infrastructure
|
||||
- Docker container with PHP 8.2 Apache
|
||||
- MySQL 8.0 container
|
||||
- Docker Compose orchestration
|
||||
- Volume persistence for database
|
||||
- Composer dependency management
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Planned Features
|
||||
- JWT authentication for REST API
|
||||
- Complete Telegram bot integration
|
||||
- Server monitoring and health checks
|
||||
- Bandwidth usage statistics
|
||||
- Client traffic analysis
|
||||
- Email notifications
|
||||
- Two-factor authentication (2FA)
|
||||
- Multi-language support
|
||||
- Dark mode UI theme
|
||||
- Automated backups
|
||||
- Rate limiting for API endpoints
|
||||
- Export/import configurations
|
||||
- Server templates for quick deployment
|
||||
- Client groups and tagging
|
||||
- Advanced logging and audit trail
|
||||
- User management admin panel
|
||||
|
||||
### Improvements Planned
|
||||
- Better error handling and user feedback
|
||||
- Real-time deployment progress updates
|
||||
- Server resource monitoring (CPU, RAM, bandwidth)
|
||||
- Client connection status tracking
|
||||
- Automatic Let's Encrypt SSL setup
|
||||
- Database connection pooling
|
||||
- Caching layer (Redis)
|
||||
- WebSocket support for real-time updates
|
||||
- Mobile-responsive improvements
|
||||
- Accessibility enhancements
|
||||
|
||||
---
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
-345
@@ -1,345 +0,0 @@
|
||||
# Testing Guide
|
||||
|
||||
This document describes how to test the Amnezia VPN Web Panel.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker and Docker Compose installed
|
||||
- Test VPS server with SSH access (for full deployment testing)
|
||||
- Amnezia VPN mobile app (Android/iOS) for QR code testing
|
||||
|
||||
## Quick Test Setup
|
||||
|
||||
### 1. Start the Application
|
||||
|
||||
```bash
|
||||
cd amnezia-web-panel
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### 2. Access the Panel
|
||||
|
||||
Open browser: `http://localhost:8082`
|
||||
|
||||
### 3. Login
|
||||
|
||||
Default credentials:
|
||||
- Email: `admin@amnez.ia`
|
||||
- Password: `admin123`
|
||||
|
||||
## Unit Tests
|
||||
|
||||
### Test QR Code Generation
|
||||
|
||||
```bash
|
||||
docker compose exec web php test_qr.php
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
✅ Success! QR code generation working correctly.
|
||||
```
|
||||
|
||||
This creates `test_qr.png` in the project root.
|
||||
|
||||
### Verify QR Code Payload
|
||||
|
||||
```bash
|
||||
# Compare payload with original implementation
|
||||
php /tmp/test_compare_qr.php
|
||||
```
|
||||
|
||||
The payload should match exactly with the original Amnezia QR format.
|
||||
|
||||
## Integration Tests
|
||||
|
||||
### Test 1: User Registration
|
||||
|
||||
1. Logout from admin account
|
||||
2. Click "Register"
|
||||
3. Fill in:
|
||||
- Name: "Test User"
|
||||
- Email: "test@example.com"
|
||||
- Password: "testpass123"
|
||||
4. Click "Register"
|
||||
5. ✅ Should redirect to dashboard
|
||||
|
||||
### Test 2: Server Creation (Without Deployment)
|
||||
|
||||
1. Go to "Servers" → "Add Server"
|
||||
2. Fill in:
|
||||
- Name: "Test Server"
|
||||
- Host: "192.168.1.100"
|
||||
- Port: 22
|
||||
- Username: "root"
|
||||
- Password: "dummy"
|
||||
3. Click "Add Server" (will fail at deployment, but server record created)
|
||||
4. ✅ Should see server in list with "pending" status
|
||||
|
||||
### Test 3: Full Server Deployment (Requires Real VPS)
|
||||
|
||||
**Prerequisites**: Remote Linux server with SSH access
|
||||
|
||||
1. Go to "Servers" → "Add Server"
|
||||
2. Fill in real server credentials:
|
||||
- Name: "Production Server 1"
|
||||
- Host: "your.server.ip"
|
||||
- Port: 22
|
||||
- Username: "root"
|
||||
- Password: "your_ssh_password"
|
||||
3. Click "Add Server"
|
||||
4. Wait for deployment (5-10 minutes)
|
||||
5. ✅ Server status should change to "active"
|
||||
6. ✅ Server should show public key and VPN port
|
||||
|
||||
### Test 4: Client Creation
|
||||
|
||||
**Prerequisites**: Active server from Test 3
|
||||
|
||||
1. Click on active server
|
||||
2. In "Create Client" section, enter name: "test-client-1"
|
||||
3. Click "Create"
|
||||
4. ✅ Should redirect to client view page
|
||||
5. ✅ Should see QR code displayed
|
||||
6. ✅ "Download Config" button should work
|
||||
|
||||
### Test 5: QR Code Scanning
|
||||
|
||||
**Prerequisites**: Amnezia VPN app installed on phone
|
||||
|
||||
1. Create a client (Test 4)
|
||||
2. Open Amnezia VPN app
|
||||
3. Tap "Add server" → "Scan QR code"
|
||||
4. Scan the QR code from web panel
|
||||
5. ✅ Configuration should be imported successfully
|
||||
6. ✅ Connect to VPN should work
|
||||
7. ✅ Check IP address changed (e.g., whatismyip.com)
|
||||
|
||||
### Test 6: Configuration Download
|
||||
|
||||
1. Go to client details page
|
||||
2. Click "Download Config"
|
||||
3. ✅ Should download `.conf` file
|
||||
4. Open file in text editor
|
||||
5. ✅ Should contain valid WireGuard config with:
|
||||
- [Interface] section with PrivateKey, Address, DNS
|
||||
- AWG parameters (Jc, Jmin, Jmax, S1, S2, H1-H4)
|
||||
- [Peer] section with PublicKey, PresharedKey, Endpoint
|
||||
6. Import manually into Amnezia VPN app
|
||||
7. ✅ Should work same as QR code
|
||||
|
||||
### Test 7: Multiple Clients
|
||||
|
||||
1. Create 5 clients on same server
|
||||
2. ✅ Each should get unique IP (10.8.1.2, 10.8.1.3, etc.)
|
||||
3. ✅ Each should have unique keys
|
||||
4. ✅ All QR codes should scan successfully
|
||||
5. Test connections from multiple devices
|
||||
6. ✅ All should connect simultaneously
|
||||
|
||||
### Test 8: Client Deletion
|
||||
|
||||
1. Go to client details
|
||||
2. Click "Delete"
|
||||
3. ✅ Client should be removed from database
|
||||
4. ⚠️ **Known Issue**: Not yet removed from server wg0.conf
|
||||
|
||||
### Test 9: Server Deletion
|
||||
|
||||
1. Go to server list
|
||||
2. Click "Delete" on a server
|
||||
3. ✅ Server should be removed from database
|
||||
4. ⚠️ **Known Issue**: Docker container not removed from remote server
|
||||
|
||||
### Test 10: Access Control
|
||||
|
||||
1. Create new user account
|
||||
2. Login as new user
|
||||
3. Create a server
|
||||
4. Logout and login as admin
|
||||
5. ✅ Admin should see all servers (including user's)
|
||||
6. Login as regular user
|
||||
7. ✅ Regular user should only see their own servers
|
||||
|
||||
## Security Tests
|
||||
|
||||
### Test 11: SQL Injection Protection
|
||||
|
||||
Try creating server with malicious name:
|
||||
```
|
||||
Name: Test'; DROP TABLE vpn_servers; --
|
||||
```
|
||||
|
||||
✅ Should be safely escaped, no SQL error
|
||||
|
||||
### Test 12: XSS Protection
|
||||
|
||||
Try creating client with script tag:
|
||||
```
|
||||
Name: <script>alert('XSS')</script>
|
||||
```
|
||||
|
||||
✅ Should be HTML-escaped in output
|
||||
|
||||
### Test 13: Authentication
|
||||
|
||||
1. Logout
|
||||
2. Try accessing `/dashboard` directly
|
||||
3. ✅ Should redirect to login page
|
||||
|
||||
### Test 14: Password Security
|
||||
|
||||
1. Check database:
|
||||
```bash
|
||||
docker compose exec db mysql -u amnezia -pamnezia123 amnezia_panel
|
||||
SELECT password FROM users LIMIT 1;
|
||||
```
|
||||
|
||||
✅ Password should be bcrypt hash, not plaintext
|
||||
|
||||
## Performance Tests
|
||||
|
||||
### Test 15: Multiple Concurrent Requests
|
||||
|
||||
```bash
|
||||
# Install Apache Bench
|
||||
sudo apt install apache2-utils
|
||||
|
||||
# Test login endpoint
|
||||
ab -n 100 -c 10 -p login.txt -T application/x-www-form-urlencoded http://localhost:8082/login
|
||||
```
|
||||
|
||||
✅ Should handle 100 requests without errors
|
||||
|
||||
### Test 16: Database Connection Pooling
|
||||
|
||||
Create 10 clients rapidly:
|
||||
```bash
|
||||
for i in {1..10}; do
|
||||
curl -X POST http://localhost:8082/servers/1/clients/create \
|
||||
-d "name=client$i" \
|
||||
-b cookies.txt
|
||||
done
|
||||
```
|
||||
|
||||
✅ Should complete without connection errors
|
||||
|
||||
## Browser Compatibility
|
||||
|
||||
Test in:
|
||||
- ✅ Chrome/Edge (Chromium)
|
||||
- ✅ Firefox
|
||||
- ✅ Safari
|
||||
- ✅ Mobile browsers (iOS Safari, Chrome Android)
|
||||
|
||||
## Docker Tests
|
||||
|
||||
### Test 17: Container Health
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
✅ Both containers should be "Up" and healthy
|
||||
|
||||
### Test 18: Volume Persistence
|
||||
|
||||
```bash
|
||||
# Stop containers
|
||||
docker compose down
|
||||
|
||||
# Start again
|
||||
docker compose up -d
|
||||
|
||||
# Login
|
||||
```
|
||||
|
||||
✅ All data should persist (servers, clients, users)
|
||||
|
||||
### Test 19: Logs
|
||||
|
||||
```bash
|
||||
docker compose logs -f web
|
||||
docker compose logs -f db
|
||||
```
|
||||
|
||||
✅ No errors in logs during normal operation
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### QR Code Not Displaying
|
||||
|
||||
Check:
|
||||
```bash
|
||||
docker compose exec web php test_qr.php
|
||||
```
|
||||
|
||||
If fails, check:
|
||||
- GD extension installed: `php -m | grep gd`
|
||||
- Composer dependencies: `composer show endroid/qr-code`
|
||||
|
||||
### Can't Connect to Database
|
||||
|
||||
Check:
|
||||
```bash
|
||||
docker compose exec web php -r "
|
||||
\$pdo = new PDO('mysql:host=db;dbname=amnezia_panel', 'amnezia', 'amnezia123');
|
||||
echo 'Connected successfully';
|
||||
"
|
||||
```
|
||||
|
||||
### SSH Deployment Fails
|
||||
|
||||
Test SSH manually:
|
||||
```bash
|
||||
sshpass -p 'yourpassword' ssh -o StrictHostKeyChecking=no root@server.ip 'echo OK'
|
||||
```
|
||||
|
||||
## Test Checklist
|
||||
|
||||
Before releasing or deploying:
|
||||
|
||||
- [ ] All unit tests pass
|
||||
- [ ] QR code generation works
|
||||
- [ ] Server deployment works on real VPS
|
||||
- [ ] Client creation works
|
||||
- [ ] QR codes scan in Amnezia app
|
||||
- [ ] VPN connection works
|
||||
- [ ] Multiple clients work simultaneously
|
||||
- [ ] Authentication works
|
||||
- [ ] Access control works (user/admin)
|
||||
- [ ] SQL injection protected
|
||||
- [ ] XSS protected
|
||||
- [ ] CSRF protection (if implemented)
|
||||
- [ ] Password hashing verified
|
||||
- [ ] All browsers work
|
||||
- [ ] Mobile responsive
|
||||
- [ ] Docker containers healthy
|
||||
- [ ] Data persists after restart
|
||||
- [ ] No errors in logs
|
||||
- [ ] README instructions accurate
|
||||
- [ ] Default password changed
|
||||
|
||||
## Automated Testing (Future)
|
||||
|
||||
Consider implementing:
|
||||
- PHPUnit for unit tests
|
||||
- Selenium for browser automation
|
||||
- GitHub Actions for CI/CD
|
||||
- Code coverage reports
|
||||
- Automated security scanning
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
When reporting bugs, include:
|
||||
1. Steps to reproduce
|
||||
2. Expected behavior
|
||||
3. Actual behavior
|
||||
4. Docker logs: `docker compose logs`
|
||||
5. Browser console errors
|
||||
6. PHP version: `docker compose exec web php -v`
|
||||
7. MySQL version: `docker compose exec db mysql -V`
|
||||
|
||||
---
|
||||
|
||||
Happy Testing! 🧪
|
||||
@@ -1,278 +0,0 @@
|
||||
# Traffic Statistics & Client Management Features
|
||||
|
||||
## New Features Added (2025-11-06)
|
||||
|
||||
### 1. Traffic Statistics Tracking
|
||||
|
||||
**Database Changes:**
|
||||
- Added `bytes_sent` - Total bytes uploaded by client
|
||||
- Added `bytes_received` - Total bytes downloaded by client
|
||||
- Added `last_handshake` - Last successful WireGuard connection time
|
||||
- Added `last_sync_at` - Last time stats were synced from server
|
||||
|
||||
**Backend Methods:**
|
||||
- `VpnClient->syncStats()` - Sync single client statistics from server
|
||||
- `VpnClient::syncAllStatsForServer($serverId)` - Sync all clients on a server
|
||||
- `VpnClient->getFormattedStats()` - Get human-readable stats (KB, MB, GB)
|
||||
- `VpnClient::getClientStatsFromServer()` - Parse `wg show` output
|
||||
|
||||
**How it works:**
|
||||
1. Connects to server via SSH
|
||||
2. Runs `wg show wg0 dump` inside Docker container
|
||||
3. Parses output to extract transfer statistics
|
||||
4. Updates database with latest stats
|
||||
5. Calculates "last seen" based on handshake time
|
||||
|
||||
### 2. Client Access Control
|
||||
|
||||
**Revoke Access:**
|
||||
- Temporarily disable client without deleting
|
||||
- Removes peer from server WireGuard config
|
||||
- Keeps client record in database with status='disabled'
|
||||
- Can be restored later
|
||||
|
||||
**Restore Access:**
|
||||
- Re-enable previously revoked client
|
||||
- Re-adds peer to server WireGuard config
|
||||
- Changes status back to 'active'
|
||||
|
||||
**Delete Client:**
|
||||
- Permanently removes client
|
||||
- First revokes access (removes from server)
|
||||
- Then deletes from database
|
||||
|
||||
**Backend Methods:**
|
||||
- `VpnClient->revoke()` - Disable client access
|
||||
- `VpnClient->restore()` - Re-enable client access
|
||||
- `VpnClient->delete()` - Permanently delete client
|
||||
- `VpnClient::removeClientFromServer()` - Remove peer from wg0.conf
|
||||
- `VpnClient::removeFromClientsTable()` - Remove from clientsTable JSON
|
||||
|
||||
### 3. Web Interface Updates
|
||||
|
||||
**Server View Page (`/servers/{id}`):**
|
||||
- Added "Sync Stats" button - refreshes all client stats
|
||||
- Enhanced client table with:
|
||||
- Status badge (Active/Disabled)
|
||||
- Traffic columns (Upload/Download)
|
||||
- Last seen timestamp
|
||||
- Action buttons (View, Revoke/Restore, Delete)
|
||||
|
||||
**Client View Page (`/clients/{id}`):**
|
||||
- Added traffic statistics panel
|
||||
- Shows uploaded/downloaded/total bytes
|
||||
- Displays last handshake time
|
||||
- "Refresh" button to sync latest stats
|
||||
- Real-time status indicator (Online if handshake < 5 min)
|
||||
- Revoke/Restore button based on current status
|
||||
|
||||
### 4. API Endpoints
|
||||
|
||||
All endpoints require authentication (session-based, JWT planned).
|
||||
|
||||
**GET `/api/clients/{id}`**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"client": {
|
||||
"id": 1,
|
||||
"name": "client1",
|
||||
"server_id": 1,
|
||||
"client_ip": "10.8.1.2",
|
||||
"status": "active",
|
||||
"created_at": "2025-11-06 12:00:00",
|
||||
"stats": {
|
||||
"sent": "1.5 GB",
|
||||
"received": "3.2 GB",
|
||||
"total": "4.7 GB",
|
||||
"last_seen": "Online",
|
||||
"is_online": true
|
||||
},
|
||||
"bytes_sent": 1610612736,
|
||||
"bytes_received": 3435973836,
|
||||
"last_handshake": "2025-11-06 14:30:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**POST `/api/clients/{id}/revoke`**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Client revoked"
|
||||
}
|
||||
```
|
||||
|
||||
**POST `/api/clients/{id}/restore`**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "Client restored"
|
||||
}
|
||||
```
|
||||
|
||||
**GET `/api/servers/{id}/clients`**
|
||||
Returns all clients with synced stats for a server.
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"clients": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "client1",
|
||||
"client_ip": "10.8.1.2",
|
||||
"status": "active",
|
||||
"stats": {...},
|
||||
...
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**POST `/servers/{id}/sync-stats`**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"synced": 5
|
||||
}
|
||||
```
|
||||
|
||||
**POST `/clients/{id}/sync-stats`**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"stats": {
|
||||
"sent": "1.5 GB",
|
||||
"received": "3.2 GB",
|
||||
"total": "4.7 GB",
|
||||
"last_seen": "Online"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Web Interface
|
||||
|
||||
1. **View Client Statistics:**
|
||||
- Go to server page
|
||||
- Click "Sync Stats" to refresh all clients
|
||||
- View traffic in table or click client for details
|
||||
|
||||
2. **Revoke Client Access:**
|
||||
- In server client list, click "Revoke" next to active client
|
||||
- Confirm action
|
||||
- Client status changes to "Disabled"
|
||||
- Client can no longer connect to VPN
|
||||
|
||||
3. **Restore Client Access:**
|
||||
- Find disabled client in list
|
||||
- Click "Restore"
|
||||
- Client status changes to "Active"
|
||||
- Client can connect again
|
||||
|
||||
### API Usage (for Telegram Bot)
|
||||
|
||||
```php
|
||||
// Get client with stats
|
||||
$response = $api->get('/api/clients/1');
|
||||
$client = $response['client'];
|
||||
|
||||
echo "Traffic: {$client['stats']['total']}\n";
|
||||
echo "Status: {$client['stats']['last_seen']}\n";
|
||||
|
||||
// Revoke access
|
||||
$api->post('/api/clients/1/revoke');
|
||||
|
||||
// Restore access
|
||||
$api->post('/api/clients/1/restore');
|
||||
|
||||
// Get all server clients with stats
|
||||
$response = $api->get('/api/servers/1/clients');
|
||||
foreach ($response['clients'] as $client) {
|
||||
echo "{$client['name']}: {$client['stats']['total']}\n";
|
||||
}
|
||||
```
|
||||
|
||||
## Technical Details
|
||||
|
||||
### WireGuard Stats Format
|
||||
|
||||
The `wg show wg0 dump` command returns:
|
||||
```
|
||||
private_key public_key preshared_key endpoint allowed_ips latest_handshake transfer_rx transfer_tx persistent_keepalive
|
||||
```
|
||||
|
||||
We parse:
|
||||
- `latest_handshake` - Unix timestamp of last handshake
|
||||
- `transfer_rx` - Bytes received by server (client sent)
|
||||
- `transfer_tx` - Bytes sent by server (client received)
|
||||
|
||||
### Peer Removal
|
||||
|
||||
Removing peer from `wg0.conf`:
|
||||
```bash
|
||||
# Find and delete [Peer] block with matching PublicKey
|
||||
sed -i '/^\[Peer\]/,/^$/{/PublicKey = <key>/,/^$/d}' /opt/amnezia/awg/wg0.conf
|
||||
|
||||
# Apply changes without restart
|
||||
wg syncconf wg0 <(wg-quick strip /opt/amnezia/awg/wg0.conf)
|
||||
```
|
||||
|
||||
### Client Status Logic
|
||||
|
||||
- **Online:** Last handshake < 5 minutes ago
|
||||
- **Recently seen:** Last handshake < 1 hour ago
|
||||
- **Offline:** Last handshake > 1 hour ago
|
||||
- **Never connected:** No handshake recorded
|
||||
|
||||
## Database Migration
|
||||
|
||||
Migration file: `migrations/002_add_traffic_stats.sql`
|
||||
|
||||
To apply manually:
|
||||
```bash
|
||||
docker compose exec -T db mysql -u root -prootpassword amnezia_panel < migrations/002_add_traffic_stats.sql
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- Stats sync requires SSH connection to server
|
||||
- Each sync runs `wg show wg0 dump` command
|
||||
- For many clients, use batch sync: `VpnClient::syncAllStatsForServer()`
|
||||
- Consider caching stats and refreshing periodically (e.g., every 5 minutes)
|
||||
- Stats updates are logged in `last_sync_at` column
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- [ ] Automatic periodic stats sync (cron job)
|
||||
- [ ] Traffic usage alerts (email/Telegram)
|
||||
- [ ] Bandwidth limits per client
|
||||
- [ ] Historical traffic graphs
|
||||
- [ ] Export stats to CSV
|
||||
- [ ] Real-time WebSocket updates
|
||||
- [ ] Client connection notifications
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Stats not syncing:**
|
||||
1. Check server SSH connection
|
||||
2. Verify Docker container is running: `docker ps | grep awg`
|
||||
3. Check `wg show wg0` output inside container
|
||||
4. Review error logs
|
||||
|
||||
**Client still connecting after revoke:**
|
||||
1. Check if peer was removed from wg0.conf
|
||||
2. Verify `wg syncconf` was executed
|
||||
3. Restart WireGuard: `docker exec <container> wg-quick down wg0 && wg-quick up wg0`
|
||||
|
||||
**Last handshake not updating:**
|
||||
1. Ensure client is actually connected
|
||||
2. Check WireGuard keepalive settings (should be 25 seconds)
|
||||
3. Verify server time is synchronized (NTP)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-11-06
|
||||
**Version:** 1.1.0
|
||||
-142
@@ -1,142 +0,0 @@
|
||||
# Translation Management
|
||||
|
||||
## Database Reset & Setup
|
||||
|
||||
All translations have been reset and reloaded with complete English keys (79 total).
|
||||
|
||||
### Migration Applied
|
||||
- `migrations/006_full_translations.sql` - Complete translation reset with all 79 English keys
|
||||
|
||||
## Translation Keys Summary
|
||||
|
||||
### Categories:
|
||||
- **Authentication** (5 keys): email, login, name, password, register
|
||||
- **Clients** (17 keys): actions, add, delete, download_config, ip, etc.
|
||||
- **Dashboard** (5 keys): active_clients, title, total_clients, etc.
|
||||
- **Forms** (6 keys): cancel, close, loading, processing, save, submit
|
||||
- **Menu** (6 keys): clients, dashboard, logout, servers, settings, users
|
||||
- **Messages** (6 keys): confirm, deleted, deployed, error, saved, success
|
||||
- **Servers** (12 keys): actions, add, clients, delete, deploy, etc.
|
||||
- **Settings** (17 keys): api_keys, auto_translate, translations, etc.
|
||||
- **Status** (5 keys): active, deploying, disabled, error, inactive
|
||||
|
||||
**Total: 79 keys**
|
||||
|
||||
## How to Translate All Languages
|
||||
|
||||
### Option 1: Via Web Interface
|
||||
1. Login as admin: http://localhost:8082/login
|
||||
2. Go to Settings: http://localhost:8082/settings
|
||||
3. Add your OpenRouter API key
|
||||
4. Click "Auto-translate" button for each language
|
||||
|
||||
### Option 2: Via Command Line (Recommended)
|
||||
```bash
|
||||
# First, add your OpenRouter API key via Settings page
|
||||
|
||||
# Then run the auto-translation script
|
||||
docker compose exec app php bin/translate_all.php
|
||||
```
|
||||
|
||||
This will automatically translate all 5 languages:
|
||||
- 🇷🇺 Russian (ru)
|
||||
- 🇪🇸 Spanish (es)
|
||||
- 🇩🇪 German (de)
|
||||
- 🇫🇷 French (fr)
|
||||
- 🇨🇳 Chinese (zh)
|
||||
|
||||
### Option 3: Translate Single Language
|
||||
```bash
|
||||
# Translate only Russian
|
||||
docker compose exec app php bin/translate.php ru
|
||||
|
||||
# Translate only Spanish
|
||||
docker compose exec app php bin/translate.php es
|
||||
```
|
||||
|
||||
## Current Status
|
||||
|
||||
After migration:
|
||||
```
|
||||
+---------------+-------+
|
||||
| language_code | count |
|
||||
+---------------+-------+
|
||||
| en | 79 |
|
||||
+---------------+-------+
|
||||
```
|
||||
|
||||
After auto-translation (expected):
|
||||
```
|
||||
+---------------+-------+
|
||||
| language_code | count |
|
||||
+---------------+-------+
|
||||
| de | 79 |
|
||||
| en | 79 |
|
||||
| es | 79 |
|
||||
| fr | 79 |
|
||||
| ru | 79 |
|
||||
| zh | 79 |
|
||||
+---------------+-------+
|
||||
```
|
||||
|
||||
## API Rate Limits
|
||||
|
||||
OpenRouter free models have rate limits:
|
||||
- **gemini-2.0-flash-exp:free** - Primary model
|
||||
- **meta-llama/llama-3.2-3b-instruct:free** - Fallback 1
|
||||
- **google/gemini-flash-1.5** - Fallback 2
|
||||
|
||||
The translation script includes:
|
||||
- Automatic retries with exponential backoff
|
||||
- Model fallback on rate limits
|
||||
- 5-second delay between languages
|
||||
- Batch translation for efficiency
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "OpenRouter API key not found"
|
||||
Add your API key via Settings page first:
|
||||
1. Go to http://localhost:8082/settings
|
||||
2. Enter your OpenRouter API key (format: `sk-or-v1-...`)
|
||||
3. Click Save
|
||||
|
||||
### Error: "Rate limit exceeded"
|
||||
Wait a few minutes and try again, or:
|
||||
- Use the web interface (slower but more controlled)
|
||||
- Increase delay in `bin/translate_all.php`
|
||||
- Get a paid OpenRouter API key
|
||||
|
||||
### Check Translation Progress
|
||||
```bash
|
||||
docker compose exec db sh -c 'mysql -u root -p"$MYSQL_ROOT_PASSWORD" amnezia_panel -e "
|
||||
SELECT
|
||||
l.code,
|
||||
l.name,
|
||||
COUNT(t.id) as translated,
|
||||
(SELECT COUNT(*) FROM translations WHERE language_code = \"en\") as total
|
||||
FROM languages l
|
||||
LEFT JOIN translations t ON l.code = t.language_code
|
||||
GROUP BY l.code
|
||||
ORDER BY l.code;
|
||||
"'
|
||||
```
|
||||
|
||||
## Manual Export/Import
|
||||
|
||||
### Export translations to JSON
|
||||
```bash
|
||||
docker compose exec app php -r "
|
||||
require 'vendor/autoload.php';
|
||||
require 'inc/Config.php';
|
||||
require 'inc/DB.php';
|
||||
require 'inc/Translator.php';
|
||||
Config::load('.env');
|
||||
DB::conn();
|
||||
echo Translator::exportToJson('ru');
|
||||
" > translations_ru.json
|
||||
```
|
||||
|
||||
### Import from JSON
|
||||
```php
|
||||
Translator::importFromJson('ru', file_get_contents('translations_ru.json'));
|
||||
```
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Test QR code generation with real config
|
||||
*/
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
require __DIR__ . '/inc/QrUtil.php';
|
||||
|
||||
// Sample AmneziaWG config
|
||||
$config = <<<EOT
|
||||
[Interface]
|
||||
PrivateKey = YBtGKhj6pCKHBh8GtTaLV9WqVDCK4EWqIwXqP3vCg1M=
|
||||
Address = 10.8.1.2/32
|
||||
DNS = 1.1.1.1, 1.0.0.1
|
||||
Jc = 3
|
||||
Jmin = 40
|
||||
Jmax = 70
|
||||
S1 = 86
|
||||
S2 = 3
|
||||
H1 = 1
|
||||
H2 = 2
|
||||
H3 = 3
|
||||
H4 = 4
|
||||
|
||||
[Peer]
|
||||
PublicKey = ZVfqrLBQs3MpZjGMqOmDk0nIVMmVqRWnZHQqbOoJwXk=
|
||||
PresharedKey = uOPELRGBqTqnJPqEGCPRSLVjMW3RGFOQOhMDqmWLBBo=
|
||||
Endpoint = 123.45.67.89:51820
|
||||
AllowedIPs = 0.0.0.0/0, ::/0
|
||||
PersistentKeepalive = 25
|
||||
EOT;
|
||||
|
||||
try {
|
||||
echo "Testing QR code generation...\n\n";
|
||||
|
||||
// Generate payload
|
||||
$payloadOld = QrUtil::encodeOldPayloadFromConf($config);
|
||||
echo "Payload (URL-safe base64): " . substr($payloadOld, 0, 100) . "...\n\n";
|
||||
|
||||
// Generate QR code PNG
|
||||
$dataUri = QrUtil::pngBase64($payloadOld);
|
||||
echo "QR Code Data URI: " . substr($dataUri, 0, 100) . "...\n\n";
|
||||
|
||||
// Save to file for inspection
|
||||
if (preg_match('/^data:image\/(png|svg\+xml);base64,(.+)$/', $dataUri, $m)) {
|
||||
$imageData = base64_decode($m[2]);
|
||||
$ext = $m[1] === 'svg+xml' ? 'svg' : 'png';
|
||||
$filename = __DIR__ . "/test_qr." . $ext;
|
||||
file_put_contents($filename, $imageData);
|
||||
echo "✅ QR code saved to: $filename\n";
|
||||
}
|
||||
|
||||
echo "\n✅ Success! QR code generation working correctly.\n";
|
||||
|
||||
} catch (Throwable $e) {
|
||||
echo "❌ Error: " . $e->getMessage() . "\n";
|
||||
echo "Stack trace:\n" . $e->getTraceAsString() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user