nigig-org/nimanyatta
arena-agent f9c12359bf
Some checks failed
repo hygiene / hygiene (push) Has been cancelled
nimanyatta: drop vendored xitca-web, use crates.io sources
Delete the vendored xitca-web framework checkout at repo root and
repoint all consumers at the published crates:

- nimanyatta/Cargo.toml: drop path overrides on xitca-web (deps +
  dev-deps), remove the xitca-client dep (never published on
  crates.io) from the manifest and the load/b_server features, and
  remove the [patch.crates-io] section that forced every xitca-*
  crate onto the vendored checkout.
- nigig-lite/crates/common: xitca-web path dep -> version 0.8 from
  crates.io (vendored snapshot was 0.8.1, identical).
- Test suites (shared_test_client, security_suite, enhanced_security,
  enhanced_security_tests) and kra-etims-sdk: migrate xitca-client
  HTTP usage to reqwest from crates.io, preserving request
  semantics (header-override order, error mapping).

Verified in a fresh clone on the pinned toolchain (1.97.1):
nigig-common checks, security/enhanced suites check, and the
session/fast/regression harness binaries build.
2026-09-26 17:16:51 +00:00
..
.github/workflows Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
benches Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
crates nimanyatta: drop vendored xitca-web, use crates.io sources 2026-09-26 17:16:51 +00:00
deploy Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
nimanyatta-app Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
nimanyatta-ui Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
src nimanyatta: drop vendored xitca-web, use crates.io sources 2026-09-26 17:16:51 +00:00
.gitignore Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
analyse_instruments.sh Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
capture_metrics.sh Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
Cargo.toml nimanyatta: drop vendored xitca-web, use crates.io sources 2026-09-26 17:16:51 +00:00
copy_code.rs Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
KNOWN_ISSUES.md nimanyatta: align the WS wire format with nimanyatta-protocol (postcard) 2026-09-26 16:31:04 +00:00
mon.sh Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
PLAN.md nimanyatta: align the WS wire format with nimanyatta-protocol (postcard) 2026-09-26 16:31:04 +00:00
README.md nimanyatta: Phase 8 — reconstruct nigig-common, repair load suites, close REST coverage gaps 2026-09-26 16:24:41 +00:00
run_instruments.sh Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00
tune Include nimanyatta as normal tree (not embedded git) 2026-09-26 09:29:36 +03:00

NiManyatta

Real-time chat server built on xitca-web, SurrealDB (in-memory), and a custom WebSocket gateway.

Quick start

# Build and run the server
cargo brct_srv          # alias: cargo run --release --bin broadcast_server --features b_server

Server binds to 0.0.0.0:PORT (default 8080).

# REST API
http://127.0.0.1:8080/health

# WebSocket
ws://127.0.0.1:8080/ws?token=<paseto-access-token>

# Prometheus metrics
http://127.0.0.1:8080/metrics

Environment variables

Variable Required Default Description
PASETO_KEY Yes (prod) — 32-byte base64 PASETO v4 symmetric key
DATABASE_PATH No in-memory Path to persistent SurrealDB data file
PORT No 8080 HTTP/WS listen port
ENVIRONMENT No development production enforces stricter config
TRUST_PROXY No false Trust X-Forwarded-For from upstream proxy
PROXY_TRUSTED_IPS No — Comma-separated peer IPs allowed to set X-Forwarded-For (see note below)
WS_ALLOWED_ORIGINS Yes (prod) (permissive) Comma-separated allowed Origin values for WebSocket upgrades (see note below)
CORS_ALLOWED_ORIGINS No — Comma-separated allowed CORS origins
SMS_PROVIDER No Console Console (prints OTP to stdout) or Http
SMS_API_URL No — External SMS provider endpoint
SMS_API_KEY No — SMS provider API key
OTEL_EXPORTER_OTLP_ENDPOINT No 127.0.0.1:4317 Set to "" to disable OTLP
ENABLE_OTEL No false Set true to enable the OTLP exporter
ACCESS_TOKEN_DURATION_SECS No 3600 Access-token lifetime
REFRESH_TOKEN_DURATION_SECS No 604800 Refresh-token lifetime

Proxy & forwarded headers (PROXY_TRUSTED_IPS)

TRUST_PROXY=true alone is not sufficient: the middleware only reads X-Forwarded-For when the TCP peer IP of the connection is listed in PROXY_TRUSTED_IPS. Requests from untrusted peers keep their raw peer address and any X-Forwarded-For header is ignored — a client cannot spoof its IP by sending the header directly.

# Example: reverse proxy on the same host and a dedicated LB subnet
TRUST_PROXY=true
PROXY_TRUSTED_IPS=127.0.0.1,::1,10.0.0.0/24

WebSocket origin validation (WS_ALLOWED_ORIGINS)

WebSocket upgrade requests are rejected with 403 when the Origin header is not in the allowlist. The allowlist supports * (any origin).

  • Development (default): an empty allowlist is permissive — every origin is accepted, so local tooling works with zero configuration.
  • Production (ENVIRONMENT=production): the config fails closed — startup is rejected unless WS_ALLOWED_ORIGINS is explicitly set. Set it to your web client origins (https://app.example.com), or deliberately to * if any origin is genuinely acceptable (e.g. an internal API).

See src/shared.rs for the full Config definition.

API

Auth (public)

Method Path Body
POST /api/v1/auth/register { "username", "password", "display_name"? }
POST /api/v1/auth/login { "username", "password" }
POST /api/v1/auth/refresh { "refresh_token" }
GET /api/v1/auth/login_types —

Auth (token required)

Method Path Body
POST /api/v1/auth/logout —

Rooms (token required)

Method Path Body / Notes
POST /api/v1/rooms/create {name?, topic?, is_direct, invite: [user_id]}
POST /api/v1/rooms/{room_id}/join {}
POST /api/v1/rooms/{room_id}/leave {reason?}
POST /api/v1/rooms/{room_id}/invite {user_id, reason?}
POST /api/v1/rooms/{room_id}/send {content: MessageContent, reply_to?}
POST /api/v1/rooms/{room_id}/messages {limit, direction, from?} (RFC 3339 from token)
PUT /api/v1/rooms/{room_id}/typing {typing: bool}
POST /api/v1/rooms/{room_id}/read_receipt 501 — receipts are recorded via the WebSocket MarkRead path until the REST storage lands
POST /api/v1/rooms/{room_id}/redact/{event_id} {reason?} (requires delete_any_message)

Roles (token required)

Method Path Description
POST /api/v1/admin/server-role Set server role
POST /api/v1/rooms/{room_id}/role Set room role
GET /api/v1/rooms/{room_id}/roles List room custom roles
POST /api/v1/rooms/{room_id}/roles/create Create custom role
POST /api/v1/rooms/{room_id}/roles/{role_id}/update Update custom role
POST /api/v1/rooms/{room_id}/roles/{role_id}/delete Delete custom role
POST /api/v1/rooms/{room_id}/roles/assign Assign custom role
POST /api/v1/rooms/{room_id}/roles/remove Remove custom role assignment
GET /api/v1/rooms/{room_id}/permissions Get own resolved permissions

Sync (token required)

Method Path Description
POST /api/v1/sync Full sync

SMS Auth

Method Path Description
POST /api/v1/auth/sms/request {phone_number} — request OTP (Console provider logs it)
POST /api/v1/auth/sms/verify {phone_number, code} — verify OTP + login

WebSocket

Connect to /ws?token=<access-token>. Unauthenticated connections receive a guest identity.

Messages are JSON ServerToClientMsg / ClientToServerMsg per nimanyatta-protocol.

Cargo aliases

Defined in .cargo/config.toml:

Alias Command
brct_srv cargo run --release --bin broadcast_server --features b_server
brct_srv_linux Same + uring feature
build_srv cargo build --bin broadcast_server --features b_server
stress_tester cargo run --release --bin chat_load_tester --features load
consistency_tester cargo run --release --bin chat_load_tester_consistency --features load
real_tester cargo run --release --bin chat_load_tester_realistic --features load

Deployment

See deploy/ for Ubuntu VPS hardening and verification scripts.

Known issues

See KNOWN_ISSUES.md.