Conversation
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
…om requirements Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Refactored all route and decorator usages of get_jwt_identity() to cast the returned user_id to int. This ensures consistent type handling for user lookups and permission checks, preventing potential issues when JWT identity is stored as a string.
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Introduces a GroupMembers component for managing group members in the frontend, including UI for adding and removing members (admin only). Updates group and user models to expose owner username, and group routes to prevent duplicate IP ranges. Adjusts dashboard and group list to display owner info, refines theme and layout styles, and exposes group member management endpoints in group.service.ts.
…aphs Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
…y-axis Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Added dynamic theme color support to NetworkGraph components using CSS variables and a custom hook, ensuring consistent appearance with light/dark themes. Enhanced chart options for better readability and appearance. Updated Stats.css to improve the visual style of network graphs, including background, padding, and responsive adjustments. Exposed UDP port 51820 in docker-compose.yml for WireGuard.
Moved backend and frontend Dockerfiles and configs into respective directories, added .dockerignore files for both, and updated docker-compose.yml to use new paths. Introduced GitHub Actions workflows for publishing Docker images on main and dev branches to streamline CI/CD.
Removes repository owner from Docker image tags in GitHub workflows for both dev and production. Adds docker-compose.local.yml for local builds, while docker-compose.yml now uses prebuilt images from ghcr.io instead of building locally.
Added IPv6 forwarding sysctls and configured the wg-network bridge to support IPv6 with a specified subnet in both docker-compose.local.yml and docker-compose.yml. This allows containers to communicate over IPv6.
Introduces structured logging throughout the backend, including new log statements for key actions and errors in client and group routes. Adds LOG_LEVEL environment variable support in .env.example, Dockerfile, config.py, and docker-compose files, and configures logging in the Flask app factory. WireGuard utility functions now log key generation attempts and fallbacks.
Introduces WG_DEFAULT_MTU and WG_DEFAULT_KEEPALIVE to .env.example and backend/config.py, allowing these WireGuard parameters to be configured via environment variables. Updates backend/app/models/settings.py to use values from Config for default settings, improving consistency and configurability.
Introduces settingsService to fetch default WireGuard settings from the backend and applies them as initial values in GroupForm when creating a new group. This centralizes default configuration and improves maintainability.
Implements backend logic for saving, deleting, and syncing WireGuard server/client configs, starting/stopping interfaces, and updating stats. Adds API endpoints and frontend controls for toggling WireGuard, downloading all configs as ZIP, and refreshing stats. Updates models, routes, utility functions, and UI to support real-time WireGuard management and configuration export.
Improves WireGuard server config generation to support granular client-to-client communication restrictions and IPv6 rules. Adds per-client traffic stats to backend API and displays client breakdown in the frontend stats page. Refactors group and traffic stats components for auto-refresh, better UI, and removes manual stats update buttons.
…systemd persistence Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
…ntegration Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Eliminated margin, padding, and border-top styles from the .form-actions section in ClientForm.css, GroupForm.css, and UserForm.css to simplify form layouts and improve visual consistency.
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
This reverts commit 2671948.
Added owner and group links in stats tables for better navigation. Implemented traffic data aggregation in NetworkGraph components to improve performance with large datasets. Updated types and backend API to include owner_id and group_id. Improved empty state styling and removed redundant select background images in CSS.
Backend now ensures WireGuard listen_port is unique for each group during creation and update, with auto-assignment if not provided. Updated frontend theme colors to WireGuard palette and improved empty state spacing in GroupList. Added WireGuard SVG logo to public assets.
Introduces a new Footer component with styling, displaying trademark info and a GitHub source link. Integrates Footer into both the dashboard layout and login page for consistent branding and navigation. Refactors layout and login CSS for improved structure and responsiveness.
- Extract date parsing logic into reusable helper function - Add input sanitization helpers for filenames and interface names - Add command injection protection with interface name validation - Add security headers (X-Frame-Options, CSP, HSTS, etc.) - Add health check endpoints (/api/health and /api/ready) - Add Docker health checks to compose file Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
…nced README - Create SECURITY.md with security best practices and hardening guide - Create DEPLOYMENT.md with production deployment instructions - Enhance README with better structure, troubleshooting, and performance tips - Add health check documentation - Add security checklist - Add acknowledgments and support sections Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
- Fix gunicorn vulnerability (update to v22.0.0) - Add comprehensive security audit report (SECURITY-AUDIT.md) - Add FAQ documentation (FAQ.md) - Update CHANGELOG with all security improvements - Pin all Python dependencies with minimum versions - Update README to reference all documentation Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
- Fix interface name validation to prevent leading hyphens (^[a-z0-9][a-z0-9\-]{0,14}$)
- Align sanitize_interface_name to match validation pattern
- Improve CSP policy to allow inline styles/scripts for frontend
- Remove unnecessary commit() from health check (performance improvement)
- All patterns now consistent across codebase
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Implements a self-service user profile edit route and UI, allowing users to update their own email and password. Updates navigation, layout, and user detail components to support profile editing, and refactors UserForm to distinguish between admin and self-service editing modes. Also updates the app title in index.html and improves sidebar user info styling.
Removed unused environment variables and IPAM config from docker-compose files, added healthchecks, and made WireGuard port configurable. Updated frontend styles for user info and links, improved group and stats tables to show IPv6 ranges, and deleted unused dev agent config.
There was a problem hiding this comment.
Pull request overview
This PR introduces the complete frontend implementation for the WireGuard Multi-Client WebUI version 1.0.0, a comprehensive web interface for managing WireGuard VPN configurations, groups, clients, and users.
Key Changes:
- Complete React/TypeScript frontend with routing, authentication, and state management
- Service layer for API communication (auth, groups, clients, users, stats, settings)
- Full component library including dashboards, forms, lists, and detail views
- Responsive design with dark/light theme support
- Traffic monitoring and visualization with Chart.js integration
Reviewed changes
Copilot reviewed 99 out of 109 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/tsconfig.json | TypeScript configuration for React app with ES5 target |
| frontend/src/types/index.ts | Comprehensive type definitions for all domain entities |
| frontend/src/utils/helpers.ts | Utility functions for formatting, file download, and data aggregation |
| frontend/src/services/*.ts | API service layer for backend communication |
| frontend/src/components/auth/* | Login component with theme toggle |
| frontend/src/components/dashboard/* | Main dashboard, layout, and footer |
| frontend/src/components/groups/* | Group management components (list, detail, form, members) |
| frontend/src/components/clients/* | Client management components (list, detail, form) |
| frontend/src/components/users/* | User management components (list, detail, form) |
| frontend/src/components/stats/* | Statistics and traffic visualization components |
| frontend/src/App.tsx | Main application routing and authentication logic |
| frontend/src/App.css | Global styles with theme variables |
| frontend/public/* | Static assets and manifest files |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import statsService from '../../services/stats.service'; | ||
| import groupService from '../../services/group.service'; | ||
| import { StatsOverview, Group, User } from '../../types'; | ||
| import { formatBytes } from '../../utils/helpers'; |
There was a problem hiding this comment.
Unused import formatBytes.
| }); | ||
| const [loading, setLoading] = useState(false); | ||
| const [error, setError] = useState(''); | ||
| const [defaults, setDefaults] = useState<any>(null); |
There was a problem hiding this comment.
Unused variable defaults.
| return <div className="group-traffic-error">{error}</div>; | ||
| } | ||
|
|
||
| const hasData = trafficData && (trafficData.group_data.length > 0 || trafficData.clients.some(c => c.data.length > 0)); |
There was a problem hiding this comment.
Unused variable hasData.
| import groupService from '../../services/group.service'; | ||
| import { User, Group } from '../../types'; | ||
| import { formatDate } from '../../utils/helpers'; | ||
| import { Pencil, Lock, Unlock, Mail, User as UserIcon, FolderOpen } from 'lucide-react'; |
There was a problem hiding this comment.
Unused imports FolderOpen, Mail, UserIcon.
| </div> | ||
|
|
||
| {/* Group Traffic Statistics Section */} | ||
| {group && ( |
There was a problem hiding this comment.
This use of variable 'group' always evaluates to true.
backend/app/routes/groups.py
Outdated
| import ipaddress | ||
| import zipfile | ||
| import io | ||
| import os |
There was a problem hiding this comment.
Import of 'os' is not used.
| import os |
backend/app/routes/health.py
Outdated
| import logging | ||
| from flask import Blueprint, jsonify | ||
| from app import db | ||
| from app.models.group import Group |
There was a problem hiding this comment.
Import of 'Group' is not used.
| from app.models.group import Group |
backend/app/utils/helpers.py
Outdated
| import logging | ||
| import re | ||
| from datetime import datetime | ||
| from functools import wraps |
There was a problem hiding this comment.
Import of 'wraps' is not used.
| from functools import wraps |
| from flask import jsonify | ||
| from flask_jwt_extended import get_jwt_identity | ||
| from app.models.user import User | ||
| from app.models.group import Group |
There was a problem hiding this comment.
Import of 'Group' is not used.
| from app.models.group import Group |
| from flask_jwt_extended import get_jwt_identity | ||
| from app.models.user import User | ||
| from app.models.group import Group | ||
| from app.models.client import Client |
There was a problem hiding this comment.
Import of 'Client' is not used.
| from app.models.client import Client |
|
@copilot open a new pull request to apply changes based on the comments in this thread |
|
@Arthur2500 I've opened a new pull request, #17, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Co-authored-by: Arthur2500 <98665507+Arthur2500@users.noreply.github.com>
Updated routing in App.tsx to pass the user prop to GroupList and ClientList. Modified both components to accept the user prop and conditionally render creation actions based on user permissions.
Remove unused imports and variables flagged in code review
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 99 out of 109 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 5. Login with default credentials: | ||
| - Username: `admin` | ||
| - Password: `admin` | ||
|
|
||
| **Change the admin password immediately after first login!** |
There was a problem hiding this comment.
The documentation states that the default admin credentials are admin:admin without indicating that a password change is technically enforced, which makes full administrative access trivially guessable if the UI is reachable from an untrusted network. An attacker who can reach the login page can simply authenticate as admin and take over all groups, clients, and WireGuard configuration. To remediate, remove the static default password by generating a strong random initial password (or requiring an explicit ADMIN_PASSWORD on first run) and enforce a mandatory password change on first login before allowing any other actions.
| 5. Login with default credentials: | |
| - Username: `admin` | |
| - Password: `admin` | |
| **Change the admin password immediately after first login!** | |
| 5. On first run, set a secure admin password by specifying the `ADMIN_PASSWORD` environment variable in your `.env` file: | |
| - `ADMIN_PASSWORD=your-strong-password` | |
| **You must set a strong admin password before deploying. Do NOT use `admin:admin` in production.** | |
| If `ADMIN_PASSWORD` is not set, a strong random password will be generated and printed to the application logs on first startup. | |
| The application enforces a password change on first login if a default or weak password is detected. |
| #### 2. Change Default Admin Password | ||
|
|
||
| The default admin credentials are `admin:admin`. **Change this immediately after first login!** | ||
|
|
||
| 1. Log in as admin | ||
| 2. Navigate to your profile | ||
| 3. Change password to a strong, unique password | ||
|
|
||
| Alternatively, set a custom admin password before first startup: | ||
| ```bash | ||
| ADMIN_PASSWORD=$(openssl rand -base64 16) | ||
| echo "ADMIN_PASSWORD=${ADMIN_PASSWORD}" >> .env | ||
| ``` |
There was a problem hiding this comment.
The security policy documents a default admin account with credentials admin:admin and only advises operators to change it, which leaves a trivially guessable administrative login if the UI is exposed and the password is not changed promptly. Anyone who can reach the login endpoint can immediately authenticate as admin and compromise all VPN groups, clients, and keys. Instead, avoid shipping a fixed default password by requiring a secure ADMIN_PASSWORD to be set (or generating a random one and surfacing it out-of-band) and enforce a forced password change workflow on first login.
No description provided.