chore: initial project scaffold with admin web, backend, desktop client, and deployment setup

Add monorepo structure for NexaVPN WireGuard control plane including:
- .gitignore for node_modules, build artifacts, and environment files
- README with project overview, monorepo layout, and quick start guide
- Admin web UI with React, Vite, TypeScript, and nginx reverse proxy
- API client with type definitions for users, devices, policies, gateways, and audit logs
- Admin pages for dashboard, users, devices, policies, g
This commit is contained in:
2026-03-15 16:32:34 +01:00
commit 830491cb0d
91 changed files with 5279 additions and 0 deletions

76
docs/enrollment.md Normal file
View File

@@ -0,0 +1,76 @@
# Device Enrollment And Auto-Provisioning
## Enrollment Flow
1. The user launches the desktop client.
2. The client shows a minimal form with:
- server URL
- username
- password
3. The client validates the server URL and performs a TLS reachability check.
4. The user submits credentials.
5. The client calls `POST /api/v1/auth/login`.
6. On success, the client securely stores:
- access token
- refresh token
- remembered server URL
7. The client generates a WireGuard keypair locally.
8. The client computes a stable device fingerprint.
9. The client calls `POST /api/v1/devices/enroll`.
10. The backend:
- creates or updates the device record
- selects an active gateway
- allocates a VPN IP
- resolves effective policy destinations
- stores the peer
- renders the WireGuard profile
- emits audit events
11. The client stores the profile locally in secure application storage.
12. The client registers the profile with the local tunnel manager.
13. The post-login view shows:
- connection status
- assigned VPN IP
- allowed resources
- connect/disconnect button
- last sync time
## Private Key Handling
- The WireGuard private key is generated on-device.
- It is never sent to the backend.
- The backend stores only the public key and provisioning metadata.
- The desktop app keeps the private key inside the OS-secured storage boundary where possible.
## Auto-Profile Provisioning Design
The provisioning response returns both structured metadata and a rendered WireGuard config. The client uses the rendered config for immediate compatibility and the structured metadata for UI status.
### Preferred MVP Strategy
Use an embedded tunnel manager inside the Tauri app:
- Windows
- manage the tunnel using a Rust bridge and local service abstraction
- support future integration with WireGuardNT or the official service
- macOS
- manage the tunnel through a privileged helper or Network Extension bridge in a later hardening phase
- MVP keeps the app abstraction stable while platform backends can evolve
This approach keeps the user flow consistent even if the platform-specific implementation differs.
### Fallback Strategy
If native embedded control is not ready on a platform:
- the app still auto-creates the profile locally
- the app exposes a one-click import handoff to the system WireGuard client
- this fallback is clearly labeled as temporary in documentation, not as the intended end state
## Reprovisioning
- Profile rotation increments `profile_revision`.
- On next sync or forced refresh, the client fetches a new profile.
- Revoked devices lose access because:
- the gateway peer is removed
- tokens can be invalidated
- the client marks the local profile unusable