|
Some checks failed
repo hygiene / hygiene (push) Has been cancelled
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. |
||
|---|---|---|
| .. | ||
| .github/workflows | ||
| benches | ||
| crates | ||
| deploy | ||
| nimanyatta-app | ||
| nimanyatta-ui | ||
| src | ||
| .gitignore | ||
| analyse_instruments.sh | ||
| capture_metrics.sh | ||
| Cargo.toml | ||
| copy_code.rs | ||
| KNOWN_ISSUES.md | ||
| mon.sh | ||
| PLAN.md | ||
| README.md | ||
| run_instruments.sh | ||
| tune | ||
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 unlessWS_ALLOWED_ORIGINSis 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.