You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+33-31Lines changed: 33 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -265,7 +265,7 @@ The repository’s `config/` directory holds **server** runtime files and the **
265
265
266
266
### Diagnostics (`-doctor`)
267
267
268
-
Run **`./marchat-client -doctor`** or **`./marchat-server -doctor`** for a text report (paths, masked `MARCHAT_*` env, sanity checks). **Server** doctor lists `MARCHAT_*`**after** loading the resolved config directory’s **`.env`** (same as the running server), so values are not limited to what your shell exported. **Client** doctor only shows variables present in the client process (it does not read the server’s `config/.env`). Server doctor also reports the detected DB dialect, validates the configured DB connection string format, and attempts a DB ping. On a **color-capable terminal** (stdout is a TTY), the text report uses **ANSI colors** aligned with the server pre-TUI banner; set **`NO_COLOR`** or redirect to a file/pipe for **plain** output. Use **`-doctor-json`** for machine-readable output (never colorized). If both flags were passed, `-doctor-json` wins. Exits without starting the TUI or listening on a port. See [ARCHITECTURE.md](ARCHITECTURE.md) for details.
268
+
Run **`./marchat-client -doctor`** or **`./marchat-server -doctor`** for a text report (paths, redacted `MARCHAT_*` secrets as length-only, other env values as shown, sanity checks). **Server** doctor lists `MARCHAT_*` **after** loading the resolved config directory’s **`.env`** (same as the running server), so values are not limited to what your shell exported. **Client** doctor only shows variables present in the client process (it does not read the server’s `config/.env`). Server doctor also reports the detected DB dialect, validates the configured DB connection string format, and attempts a DB ping. On a **color-capable terminal** (stdout is a TTY), the text report uses **ANSI colors** aligned with the server pre-TUI banner; set **`NO_COLOR`** or redirect to a file/pipe for **plain** output. Use **`-doctor-json`** for machine-readable output (never colorized). If both flags were passed, `-doctor-json` wins. Exits without starting the TUI or listening on a port. See [ARCHITECTURE.md](ARCHITECTURE.md) for details.
269
269
270
270
## Admin Commands
271
271
@@ -699,42 +699,44 @@ Profiles stored in platform-appropriate locations:
699
699
700
700
| Issue | Solution |
701
701
|-------|----------|
702
-
| Wrong config folder / paths | Run `marchat-client -doctor` or `marchat-server -doctor`; see **Client vs server config locations**|
703
-
| Connection failed | Verify `ws://` or `wss://` protocol in URL |
704
-
|`wss://localhost:8443` reconnect loop / connection refused | Ensure Caddy is up: `docker compose -f docker-compose.proxy.yml up -d`, or use `ws://127.0.0.1:8080/ws` without the proxy ([reverse proxy guide](deploy/CADDY-REVERSE-PROXY.md)) |
705
-
| Admin commands not working | Check `--admin` flag and correct `--admin-key`|
| PostgreSQL connection fails | Verify URL format: `postgres://user:pass@host:5432/db?sslmode=disable`; test with `psql` using same creds |
710
-
| MySQL connection fails | Verify DSN prefix `mysql:` and DSN body `user:pass@tcp(host:3306)/db?parseTime=true`; test with `mysql` CLI |
711
-
| SQL syntax error after backend switch | Ensure tables were created by the current server version and restart after changing `MARCHAT_DB_PATH`|
712
-
| Message history missing | Expected after updates - user states reset for ban/unban improvements |
713
-
| Ban history gaps not working | Ensure `MARCHAT_BAN_HISTORY_GAPS=true` (disabled by default) and `ban_history` table exists |
714
-
| TLS certificate errors | Use `--skip-tls-verify` for dev with self-signed certs |
715
-
| Plugin installation fails | Verify `MARCHAT_PLUGIN_REGISTRY_URL` is accessible and valid JSON |
716
-
| E2E encryption errors | Ensure `--e2e` and keystore passphrase; see **[E2E Encryption](#e2e-encryption)** (keystore format, env var vs file). Check debug logs. |
717
-
| Global E2E key errors | Verify key is valid base64-encoded 32-byte key: `openssl rand -base64 32`. Remember: **`MARCHAT_GLOBAL_E2E_KEY` overrides** the keystore for that session without saving to disk. |
718
-
| Blank encrypted messages | Fixed in v0.3.0-beta.5+ - ensure latest version |
719
-
| Username already taken | Use admin `:forcedisconnect <user>` or wait 5min for auto-cleanup |
720
-
| Stale connections | Server auto-cleans every 5min, or admin use `:cleanup`|
721
-
| Client frozen at startup | Fixed in latest - `--quick-start` uses proper UI |
722
-
| Multi-line input not working | Use `Alt+Enter` or `Ctrl+J`; `Shift+Enter` is not supported in most Windows terminals |
702
+
| Wrong config folder / paths | Run `./marchat-client -doctor` or `./marchat-server -doctor` (add `-doctor-json` for scripts; set `NO_COLOR` for plain text). See **Client vs server config locations**. **Server:** if you set `MARCHAT_CONFIG_DIR` only in `config/.env`, restart after saving—the loader re-reads it after `Overload`. |
703
+
| Connection failed | Use `ws://` or `wss://` and the path your server uses (default HTTP handler is **`/ws`**—e.g. `ws://host:8080/ws`). |
704
+
|`wss://localhost:8443` reconnect loop / connection refused | Ensure Caddy (or your proxy) is up: `docker compose -f docker-compose.proxy.yml up -d`, or connect directly with `ws://127.0.0.1:8080/ws` ([reverse proxy guide](deploy/CADDY-REVERSE-PROXY.md)). |
705
+
| Admin commands not working | Client must use **`--admin`** and **`--admin-key`** matching the server’s `MARCHAT_ADMIN_KEY`; username must be listed in `MARCHAT_USERS`. |
706
+
| Clipboard issues (Linux) | Install a clipboard tool (e.g. `sudo apt install xclip` or `xsel`). |
707
+
| Port in use | Set `MARCHAT_PORT` (e.g. `8081`) in the environment or `config/.env` and restart the server. |
708
+
| Database migration fails | Check file permissions; back up the database before upgrades; run the **same** server binary version that created the schema. |
709
+
| PostgreSQL connection fails | Verify URL format: `postgres://user:pass@host:5432/db?sslmode=disable`; test with `psql` using the same credentials. |
710
+
| MySQL connection fails | Verify DSN prefix `mysql:` and body `user:pass@tcp(host:3306)/db?parseTime=true`; test with the `mysql` CLI. |
711
+
| SQL syntax error after backend switch | Ensure tables were created by the current server version and restart after changing `MARCHAT_DB_PATH`. |
712
+
| Message history looks incomplete | History depends on **channel**, **per-user message state**, and server filters. **Ban/unban** and related flows can reset stored state so scrollback differs from the raw DB. |
713
+
| Ban history gaps not working | Set `MARCHAT_BAN_HISTORY_GAPS=true` (default off). The server creates the **`ban_history`** table when using a database backend that runs marchat migrations. |
714
+
| TLS certificate errors | For dev/self-signed certs, pass **`--skip-tls-verify`** on the client (or enable **Skip TLS verify** in the profile / interactive setup). |
715
+
| Plugin installation fails | Check registry URL (`MARCHAT_PLUGIN_REGISTRY_URL`), network access, and JSON validity; commercial plugins need a valid license for the **plugin name** (see **PLUGIN_ECOSYSTEM.md**). |
716
+
| E2E encryption errors | Use **`--e2e`** and the keystore passphrase; see **[E2E Encryption](#e2e-encryption)** (keystore path, `MARCHAT_GLOBAL_E2E_KEY` vs file). Client and server must share the same global key material. |
717
+
| Global E2E key errors | Key must be **base64** encoding **32 raw bytes** (`openssl rand -base64 32`). **`MARCHAT_GLOBAL_E2E_KEY`** overrides the in-memory key for that process and is **not** written to the keystore file. |
718
+
|`:savefile` picks the wrong payload when names collide | Received files are stored per sender internally, but `:savefile <name>` matches **basename only**. If two users sent the same filename, which copy is saved is **not deterministic**—ask for distinct names or avoid duplicate basenames until disambiguation is exposed in the UI. |
719
+
| Send file / nothing happens | Check the footer (**Connected** vs **Disconnected**). If disconnected, `:sendfile` should report **Not connected to server**; reconnect, then retry (including **Alt+F** after a connection is up). |
720
+
| Username already taken | A live or **stale** session may still hold the name. Admin: **`:forcedisconnect <user>`**. Otherwise the server’s **~5 minute** WebSocket ping sweep removes broken clients (or run **`:cleanup`**). |
721
+
| Stale / ghost sessions | Same as above: wait for the ping sweep, run `:cleanup`, or `:forcedisconnect`. |
722
+
| Multi-line input not working | Use **Alt+Enter** or **Ctrl+J** in the input (plain **Enter** sends). **Shift+Enter** is unreliable on many Windows terminals. |
723
+
| Doctor / CI noise | For automated checks, use `-doctor-json`. Secret values are redacted to length only (no suffix). |
723
724
724
725
### Stale Connection Management
725
726
726
-
**Automatic:**Server detects and removes stale connections every 5 minutes using WebSocket ping.
727
+
**Automatic:**The hub runs **`CleanupStaleConnections`** about every **5 minutes**: it sends a WebSocket **ping** per client; failures remove the client and free the username.
727
728
728
-
**Manual (Admin):**
729
-
```bash
730
-
:cleanup # Clean all stale connections
731
-
:forcedisconnect username # Force disconnect specific user
729
+
**Manual (admin, from the client):**
730
+
731
+
```text
732
+
:cleanup # Run stale check now for all clients
733
+
:forcedisconnect <user> # Drop a specific connected user
732
734
```
733
735
734
-
**Common scenarios:**
735
-
-Client crash/Ctrl+C: Auto-cleaned within 5 minutes
736
-
-Network interruption: Removed on next cleanup cycle
0 commit comments