Files
docs/core.md
T
2026-06-11 18:35:54 +03:00

8.9 KiB

Core

Core is the Nexuma control API. It stores platform state, authenticates users, coordinates nodes, builds node configuration revisions, records traffic, and serves public subscription exports.

This page is public operator documentation. It describes behavior, API, environment variables, and Docker deployment without requiring source-code access.

Capabilities

  • User registration, login, Telegram OAuth, account approval, profile updates, and role-based access.
  • Tariff management with price, duration, traffic limit, protocol permissions, node permissions, and external subscription sources.
  • Subscription lifecycle with activation, cancellation, expiry, auto-renewal, traffic accounting, and public links.
  • Balance management with deposit, withdrawal, refund, history, and auto-renewal charging rules.
  • Node registration through one-time codes.
  • Node heartbeat, status, sync state, revision tracking, config delivery, and error reporting.
  • Per-node protocol configuration, routing configuration, masking sites, runtime operations, and outbounds.
  • Routing rule sets with rules, balancers, and blocking options.
  • External subscription source ingestion and testing.
  • Public subscription exports for VPN clients.
  • Platform settings management (panel, subscription delivery, Telegram, IP information provider).
  • User IP history with country, city, ISP, and ASN enrichment through IPinfo.io or ip-api.com.
  • OAuth-based DonationAlerts integration with automatic token refresh and RUB balance deposits linked by user UUID.
  • DonatePay API integration with automatic RUB balance deposits linked by UUID in the donation comment.
  • Telegram broadcast messages with user filtering and delivery tracking.
  • Referral system with code-based self-approval for pending users.
  • Audit logs, usage queries, metrics, and health checks.

Environment Variables

Variable Required Default Description
PORT No 3000 HTTP port.
GRPC_PORT No 3002 gRPC port for node-to-core communication. Expose this port to node servers.
NODE_ENV No development Runtime mode.
DB_HOST Yes localhost Database host.
DB_PORT No 5432 Database port.
DB_USER Yes postgres Database user.
DB_PASSWORD Yes empty Database password.
DB_NAME Yes nexuma Database name.
REDIS_HOST Yes localhost Redis host.
REDIS_PORT No 6379 Redis port.
REDIS_PASSWORD No empty Redis password.
REDIS_DB No 0 Redis database index.
JWT_SECRET Yes insecure dev value Access token secret. Use a long random value.
JWT_EXPIRES_IN No 15m Access token lifetime.
JWT_REFRESH_SECRET Yes insecure dev value Refresh token secret. Use a different long random value.
JWT_REFRESH_EXPIRES_IN No 7d Refresh token lifetime.
TELEGRAM_BOT_TOKEN No empty Enables Telegram login and notifications.
CORS_ORIGINS No * Comma-separated allowed origins.

Docker Compose

Minimal Core deployment with Redis and an external database:

version: '3.9'

services:
  redis:
    image: redis:7-alpine
    container_name: nexuma-redis
    restart: unless-stopped
    volumes:
      - redis_data:/data
    networks:
      - nexuma

  core:
    image: nexuma/core:latest
    container_name: nexuma-core
    restart: unless-stopped
    environment:
      PORT: 3000
      GRPC_PORT: 3002
      DB_HOST: your-postgres-host
      DB_PORT: 5432
      DB_USER: postgres
      DB_PASSWORD: change-me
      DB_NAME: nexuma
      REDIS_HOST: redis
      REDIS_PORT: 6379
      JWT_SECRET: replace-with-long-random-secret
      JWT_REFRESH_SECRET: replace-with-another-long-random-secret
      JWT_EXPIRES_IN: 15m
      JWT_REFRESH_EXPIRES_IN: 7d
      CORS_ORIGINS: https://panel.example.com
    ports:
      - "3000:3000"
      - "3002:3002"
    depends_on:
      - redis
    networks:
      - nexuma
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:3000/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s

volumes:
  redis_data:

networks:
  nexuma:
    driver: bridge

Run:

docker compose up -d

Health check:

curl http://localhost:3000/health

API Conventions

  • JSON request and response bodies are used unless a route explicitly returns text, YAML, or metrics.
  • User and admin routes use Authorization: Bearer <access_token>.
  • Admin routes require an admin account.
  • Node-private routes use x-node-auth-key.
  • Public subscription content is served by UUID and does not require login.
  • Validation errors return HTTP error responses with an error message.

Public API

Method Route Purpose
GET /health Health status.
GET /metrics Metrics text output.
POST /auth/register Register with email and password.
POST /auth/login Login with email and password.
POST /auth/refresh Refresh tokens.
POST /auth/telegram Login or register through Telegram OAuth.
GET /auth/telegram/bot-id Return configured Telegram bot ID.
GET /sub/:uuid/info Return public subscription metadata.
GET /sub/:uuid Return generated VPN subscription content.

GET /sub/:uuid supports:

  • ?format=v2ray
  • ?format=clash
  • ?format=singbox

Missing or unknown format falls back to v2ray.

User API

Method Route Purpose
GET /me Current user profile.
PATCH /me/profile Update name, email, or password.
GET /me/stats User summary statistics.
GET /me/traffic Traffic series by period.
GET /me/traffic/daily Daily traffic series.
GET /me/traffic/hourly-dist Hour-of-day traffic distribution.
GET /me/balance Current balance.
GET /me/balance/transactions User balance history.
GET /me/donation-alerts Safe DonationAlerts payment settings and the current user's UUID.
GET /me/donatepay Safe DonatePay payment settings and the current user's UUID.
GET /me/subscriptions User subscriptions.
GET /me/links User subscription links.
GET /me/configs Available configs for the user.
POST /me/links Create a public link.
PATCH /me/links/:id Rename, enable, disable, or reconfigure a link.
DELETE /me/links/:id Delete a link.
POST /me/links/:id/reset Reset a link UUID.
PATCH /me/subscriptions/:id/auto-renew Toggle auto-renew.

Admin API Groups

  • /admin/users - users, approval status, block flag, profile fields, stats, referees, and IP history.
  • /admin/tariffs - tariff CRUD.
  • /admin/subscriptions - subscriptions and subscription links.
  • /admin/links - subscription link operations (reset, update, delete).
  • /admin/nodes - nodes, protocols, sync, runtime operations, masking sites, outbounds, observatory, routing balancers.
  • /admin/routing-rule-sets - reusable routing templates.
  • /admin/external-subscriptions - external source CRUD and URL testing.
  • /admin/settings - platform settings (panel, subscription delivery, Telegram, IP information provider).
  • /admin/broadcasts - Telegram broadcast messages with delivery tracking.
  • /admin/logs - audit log viewer data.
  • /admin/usage - traffic usage rows.
  • /admin/xray/parse-link - parse a proxy share link into outbound settings.

See Core API routes for the detailed route table.

Node-Private API

Node agents use two transports:

  • HTTP — registration only (POST /node/register).
  • gRPC (GRPC_PORT, default 3002) — heartbeat, usage reporting, config sync, and live stats. This is the primary node transport.

HTTP fallback routes (/node/heartbeat, /node/usage, etc.) remain available but the node agent uses gRPC by default.

See Core private node routes for the full payload contract and gRPC method table.

Data Behavior

  • Users can be active, pending, or rejected.
  • Nodes can be active, disabled, maintenance, or error.
  • Effective node status is computed from stored status and last heartbeat.
  • Subscriptions can be active, expired, or cancelled.
  • A tariff with durationMonths = null is indefinite and expires only by traffic limit or cancellation.
  • A subscription link UUID is the credential used in generated client configs.
  • Disabling or resetting a link affects generated configs on the next node sync.
  • Node config revisions increment when node-facing configuration changes.
  • Active nodes receive only active subscription clients.

Operational Notes

  • Run Core behind HTTPS in production.
  • Keep database and Redis private.
  • Use unique long secrets for access and refresh tokens.
  • Restrict CORS to the panel domain.
  • Back up the database before upgrades.
  • Rotate node auth keys if a node host is compromised.
  • Do not expose node-private endpoints directly to the internet.