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
3.7 KiB
3.7 KiB
REST API Contract
Base path: /api/v1
All responses are JSON.
Authentication
POST /auth/login
Request:
{
"username": "alice",
"password": "secret-password"
}
Response:
{
"access_token": "jwt",
"refresh_token": "opaque-token",
"expires_in": 900,
"user": {
"id": "uuid",
"username": "alice",
"display_name": "Alice",
"role": "admin"
}
}
POST /auth/refresh
Request:
{
"refresh_token": "opaque-token"
}
POST /auth/logout
Request:
{
"refresh_token": "opaque-token"
}
GET /auth/me
Returns the authenticated user and role.
User Self-Service
GET /me/devices
Returns the current user devices.
GET /me/profile
Returns profile metadata for the current active device when the client needs to resync.
Device Enrollment and Provisioning
POST /devices/enroll
Request:
{
"name": "Alice MacBook Pro",
"platform": "macos",
"os_version": "14.4",
"app_version": "0.1.0",
"device_fingerprint": "sha256:...",
"public_key": "base64-wireguard-public-key"
}
Response:
{
"device": {
"id": "uuid",
"name": "Alice MacBook Pro",
"status": "active"
},
"peer": {
"assigned_ip": "100.96.0.10/32",
"dns_servers": ["10.20.0.53"],
"allowed_ips": ["172.16.10.0/24"],
"gateway": {
"id": "uuid",
"name": "primary-gateway",
"endpoint": "vpn.example.com:51820",
"public_key": "gateway-public-key"
},
"profile_revision": 1
},
"profile": {
"format": "wireguard",
"content": "[Interface]\n..."
},
"resources": [
{
"type": "cidr",
"value": "172.16.10.0/24",
"label": "Private subnet"
}
]
}
GET /devices/{deviceId}/profile
Admin-only debug endpoint for rendered config retrieval.
POST /devices/{deviceId}/rotate
Rotates the device profile revision and forces reprovisioning.
POST /devices/{deviceId}/revoke
Revokes the device and removes it from future gateway sync output.
POST /devices/{deviceId}/heartbeat
Optional client status sync for last-seen and runtime metadata.
Connection Metadata
GET /connection/status
Returns assigned IP, latest sync time, and effective allowed resources for the current authenticated device session.
Admin: Users
GET /admin/users
POST /admin/users
GET /admin/users/{id}
PATCH /admin/users/{id}
POST /admin/users/{id}/disable
POST /admin/users/{id}/enable
POST /admin/users/{id}/password
Admin: Devices
GET /admin/devices
GET /admin/devices/{id}
PATCH /admin/devices/{id}
POST /admin/devices/{id}/revoke
POST /admin/devices/{id}/rotate
Admin: Policies
GET /admin/policies
POST /admin/policies
GET /admin/policies/{id}
PATCH /admin/policies/{id}
DELETE /admin/policies/{id}
Policy create request:
{
"name": "Finance subnet access",
"description": "Access for finance team",
"priority": 100,
"effect": "allow",
"full_tunnel": false,
"destinations": [
"172.16.20.0/24",
"172.16.21.10/32"
],
"targets": [
{
"type": "user",
"id": "uuid"
}
]
}
Admin: Gateways
GET /admin/gateways
POST /admin/gateways
GET /admin/gateways/{id}
PATCH /admin/gateways/{id}
GET /admin/gateways/{id}/sync
The sync endpoint returns the peer and firewall bundle consumed by the gateway helper.
Admin: Audit
GET /admin/audit-logs
Query params:
event_typeentity_typestatuspagepage_size
Error Format
{
"error": {
"code": "validation_error",
"message": "public_key is required"
}
}