mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 00:26:07 +02:00
feat: Add IRC gateway functionality and update documentation
This commit is contained in:
@@ -13,11 +13,19 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="#what-is-this">What</a> •
|
<a href="#what-is-this">What</a> •
|
||||||
<a href="#getting-started">Setup</a> •
|
<a href="#getting-started">Setup</a> •
|
||||||
|
<a href="#irc-gateway">IRC</a> •
|
||||||
|
<a href="#deployment-with-nginx">Deploy</a> •
|
||||||
<a href="#client-commands">Commands</a> •
|
<a href="#client-commands">Commands</a> •
|
||||||
<a href="#configuration">Config</a> •
|
<a href="#configuration">Config</a> •
|
||||||
<a href="#license">License</a>
|
<a href="#license">License</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://echohub.voidcube.cloud/">Website</a> •
|
||||||
|
<a href="https://echohub.voidcube.cloud/servers">Public Servers</a> •
|
||||||
|
<a href="https://huebyte.github.io/EchoHub/">Documentation</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img alt=".NET 10" src="https://img.shields.io/badge/.NET-10-512BD4?style=flat-square&logo=dotnet&logoColor=white" />
|
<img alt=".NET 10" src="https://img.shields.io/badge/.NET-10-512BD4?style=flat-square&logo=dotnet&logoColor=white" />
|
||||||
<img alt="SignalR" src="https://img.shields.io/badge/SignalR-Real--time-0078D4?style=flat-square" />
|
<img alt="SignalR" src="https://img.shields.io/badge/SignalR-Real--time-0078D4?style=flat-square" />
|
||||||
@@ -40,21 +48,25 @@ Each server is fully independent — no central authority, no account federation
|
|||||||
```mermaid
|
```mermaid
|
||||||
graph TD
|
graph TD
|
||||||
subgraph Server["Server"]
|
subgraph Server["Server"]
|
||||||
|
ChatSvc["ChatService"]
|
||||||
Hub["SignalR ChatHub"]
|
Hub["SignalR ChatHub"]
|
||||||
|
IRC["IRC Gateway :6667"]
|
||||||
Auth["JWT Auth"]
|
Auth["JWT Auth"]
|
||||||
DB["SQLite DB (EF Core)"]
|
DB["SQLite DB (EF Core)"]
|
||||||
Files["File Storage"]
|
Files["File Storage"]
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph Client["Client"]
|
subgraph Clients["Clients"]
|
||||||
TUI["Terminal GUI (TUI)"]
|
TUI["Terminal GUI (TUI)"]
|
||||||
Theme["Theme Engine"]
|
IRCClient["IRC Client (irssi, WeeChat, ...)"]
|
||||||
API["API Client (auto-refresh)"]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
API -- "WebSocket" --> Hub
|
TUI -- "WebSocket" --> Hub
|
||||||
API -- "REST" --> Auth
|
TUI -- "REST" --> Auth
|
||||||
Hub --> DB
|
IRCClient -- "TCP" --> IRC
|
||||||
|
Hub --> ChatSvc
|
||||||
|
IRC --> ChatSvc
|
||||||
|
ChatSvc --> DB
|
||||||
Auth --> DB
|
Auth --> DB
|
||||||
Files --> DB
|
Files --> DB
|
||||||
```
|
```
|
||||||
@@ -65,6 +77,7 @@ graph TD
|
|||||||
|
|
||||||
- **Self-hostable** — your server, your rules, your data
|
- **Self-hostable** — your server, your rules, your data
|
||||||
- **Real-time messaging** via SignalR WebSockets
|
- **Real-time messaging** via SignalR WebSockets
|
||||||
|
- **IRC gateway** — native IRC clients connect alongside TUI users, full cross-protocol messaging
|
||||||
- **JWT auth** with short-lived access tokens and 30-day refresh tokens
|
- **JWT auth** with short-lived access tokens and 30-day refresh tokens
|
||||||
- **Channels** — create, set topics, delete (no 47-step permission wizard required)
|
- **Channels** — create, set topics, delete (no 47-step permission wizard required)
|
||||||
- **File & image uploads** with actual validation (magic bytes, not just trusting the extension)
|
- **File & image uploads** with actual validation (magic bytes, not just trusting the extension)
|
||||||
@@ -122,6 +135,66 @@ Connect, register, chat. That's the whole onboarding flow.
|
|||||||
dotnet build src/EchoHub.slnx
|
dotnet build src/EchoHub.slnx
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## IRC Gateway
|
||||||
|
|
||||||
|
EchoHub includes a built-in IRC protocol gateway. Any standard IRC client can connect to the same server and chat alongside TUI users — messages flow both ways in real time.
|
||||||
|
|
||||||
|
### Enable It
|
||||||
|
|
||||||
|
In the server's `appsettings.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Irc": {
|
||||||
|
"Enabled": true,
|
||||||
|
"Port": 6667,
|
||||||
|
"ServerName": "echohub",
|
||||||
|
"Motd": "Welcome to EchoHub IRC Gateway!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connect
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# irssi
|
||||||
|
irssi -c your-server.com -p 6667 -w <password> -n <username>
|
||||||
|
|
||||||
|
# WeeChat
|
||||||
|
/server add echohub your-server.com/6667 -password=<password> -nicks=<username>
|
||||||
|
/connect echohub
|
||||||
|
```
|
||||||
|
|
||||||
|
IRC users must have an existing EchoHub account (no registration via IRC). Auth works via `PASS`/`NICK`/`USER` or SASL PLAIN.
|
||||||
|
|
||||||
|
### What Works
|
||||||
|
|
||||||
|
| Feature | How it maps to IRC |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| Text messages | Standard `PRIVMSG` (long messages split at ~400 byte chunks) |
|
||||||
|
| Images | `[Image: filename]` + download URL + ASCII art line-by-line |
|
||||||
|
| File uploads | `[File: filename] /api/files/{id}` |
|
||||||
|
| Channels | `JOIN`, `PART`, `NAMES`, `TOPIC`, `LIST` |
|
||||||
|
| Presence | `AWAY`, `WHO`, `WHOIS` |
|
||||||
|
| Status | Maps to IRC away/here |
|
||||||
|
|
||||||
|
### TLS
|
||||||
|
|
||||||
|
If running behind **nginx** (recommended), let nginx handle TLS -- see [Deployment with nginx](#deployment-with-nginx) below.
|
||||||
|
|
||||||
|
For direct TLS without a reverse proxy, the IRC gateway can terminate TLS itself:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Irc": {
|
||||||
|
"TlsEnabled": true,
|
||||||
|
"TlsPort": 6697,
|
||||||
|
"TlsCertPath": "/path/to/cert.pfx",
|
||||||
|
"TlsCertPassword": "your-password"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Client Commands
|
## Client Commands
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
@@ -172,35 +245,107 @@ dotnet build src/EchoHub.slnx
|
|||||||
| `Jwt:Secret` | *(auto-generated)* | JWT signing key |
|
| `Jwt:Secret` | *(auto-generated)* | JWT signing key |
|
||||||
| `Server:Name` | `My EchoHub Server` | Server display name |
|
| `Server:Name` | `My EchoHub Server` | Server display name |
|
||||||
| `Server:Description` | `A self-hosted EchoHub chat server` | Server description |
|
| `Server:Description` | `A self-hosted EchoHub chat server` | Server description |
|
||||||
|
| `Server:PublicServer` | `false` | List on the [public directory](https://echohub.voidcube.cloud/servers) |
|
||||||
|
| `Server:PublicHost` | *(empty)* | Public hostname for directory listing |
|
||||||
|
| `Irc:Enabled` | `false` | Enable the IRC gateway |
|
||||||
|
| `Irc:Port` | `6667` | IRC listen port |
|
||||||
|
| `Irc:TlsEnabled` | `false` | Enable TLS for IRC |
|
||||||
|
| `Irc:TlsPort` | `6697` | IRC TLS port |
|
||||||
|
| `Irc:ServerName` | `echohub` | IRC server name in protocol messages |
|
||||||
|
| `Irc:Motd` | `Welcome to EchoHub IRC Gateway!` | Message of the day |
|
||||||
| `Cors:AllowedOrigins` | *(all origins)* | CORS whitelist |
|
| `Cors:AllowedOrigins` | *(all origins)* | CORS whitelist |
|
||||||
|
|
||||||
Logging uses Serilog — console + daily rolling files with 14-day retention. Configure it in the `Serilog` section of appsettings.
|
Logging uses Serilog — console + daily rolling files with 14-day retention. Configure in the `Serilog` section.
|
||||||
|
|
||||||
|
## Deployment with nginx
|
||||||
|
|
||||||
|
Most production deployments run behind nginx. Here's a config that handles both the HTTP/WebSocket server and the IRC gateway:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
# HTTP + WebSocket (EchoHub Server API + SignalR)
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name echohub.example.com;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/echohub.example.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/echohub.example.com/privkey.pem;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:5000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# Required for SignalR WebSocket
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $http_connection;
|
||||||
|
|
||||||
|
proxy_read_timeout 86400s;
|
||||||
|
proxy_send_timeout 86400s;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Increase max upload size for file sharing
|
||||||
|
client_max_body_size 10m;
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTP → HTTPS redirect
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name echohub.example.com;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
# IRC TLS (port 6697 → plain IRC on 6667)
|
||||||
|
stream {
|
||||||
|
upstream irc_backend {
|
||||||
|
server 127.0.0.1:6667;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 6697 ssl;
|
||||||
|
proxy_pass irc_backend;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/echohub.example.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/echohub.example.com/privkey.pem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
With this setup, keep the EchoHub IRC gateway's `TlsEnabled` set to `false` — nginx terminates TLS. See the full example at [`examples/nginx.conf`](examples/nginx.conf).
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```text
|
```text
|
||||||
src/
|
src/
|
||||||
├── EchoHub.Core/ # Shared models, DTOs, contracts, validation
|
├── EchoHub.Core/ # Shared models, DTOs, contracts, validation
|
||||||
│ ├── Constants/ # ValidationConstants, HubConstants
|
│ ├── Constants/ # ValidationConstants, HubConstants
|
||||||
│ ├── Contracts/ # IEchoHubClient (SignalR interface)
|
│ ├── Contracts/ # IChatService, IChatBroadcaster, IEchoHubClient
|
||||||
│ ├── DTOs/ # Record DTOs
|
│ ├── DTOs/ # Record DTOs
|
||||||
│ └── Models/ # Entity models
|
│ └── Models/ # Entity models
|
||||||
│
|
│
|
||||||
├── EchoHub.Server/ # ASP.NET Core server
|
├── EchoHub.Server/ # ASP.NET Core server
|
||||||
│ ├── Auth/ # JWT token service
|
│ ├── Auth/ # JWT token service
|
||||||
│ ├── Controllers/ # REST API endpoints
|
│ ├── Controllers/ # REST API endpoints
|
||||||
│ ├── Data/ # EF Core DbContext + migrations
|
│ ├── Data/ # EF Core DbContext + migrations
|
||||||
│ ├── Hubs/ # SignalR ChatHub
|
│ ├── Hubs/ # SignalR ChatHub
|
||||||
│ ├── Services/ # Presence, file storage, image processing
|
│ ├── Services/ # ChatService, presence, file storage, image processing
|
||||||
│ └── Setup/ # First-run setup, DB initialization
|
│ └── Setup/ # First-run setup, DB initialization
|
||||||
│
|
│
|
||||||
├── EchoHub.Client/ # Terminal.Gui TUI client
|
├── EchoHub.Server.Irc/ # IRC protocol gateway
|
||||||
│ ├── Config/ # Client configuration
|
│ ├── IrcGatewayService # TCP listener (BackgroundService)
|
||||||
│ ├── Services/ # API client, SignalR connection
|
│ ├── IrcCommandHandler # IRC command dispatch (JOIN, PRIVMSG, etc.)
|
||||||
│ ├── Themes/ # 6 built-in themes
|
│ ├── IrcBroadcaster # Fans chat events to IRC connections
|
||||||
│ └── UI/ # MainWindow, dialogs, chat renderer
|
│ └── IrcMessageFormatter # MessageDto → IRC PRIVMSG lines
|
||||||
│
|
│
|
||||||
└── EchoHub.slnx # Solution file
|
├── EchoHub.Client/ # Terminal.Gui TUI client
|
||||||
|
│ ├── Config/ # Client configuration
|
||||||
|
│ ├── Services/ # API client, SignalR connection
|
||||||
|
│ ├── Themes/ # 13 built-in themes
|
||||||
|
│ └── UI/ # MainWindow, dialogs, chat renderer
|
||||||
|
│
|
||||||
|
└── EchoHub.slnx # Solution file
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ Articles related to the EchoHub.Core shared library.
|
|||||||
## Topics
|
## Topics
|
||||||
|
|
||||||
- Data models and DTOs
|
- Data models and DTOs
|
||||||
- SignalR contract interface
|
- Contract interfaces (IChatService, IChatBroadcaster, IEchoHubClient)
|
||||||
- Validation constants and shared rules
|
- Validation constants and shared rules
|
||||||
|
|||||||
+6
-2
@@ -10,8 +10,12 @@ Terminal.Gui v2 TUI application -- UI components, services, themes, and configur
|
|||||||
|
|
||||||
### Core
|
### Core
|
||||||
|
|
||||||
Shared library -- DTOs, models, constants, and the SignalR client contract.
|
Shared library -- DTOs, models, constants, and contracts (`IChatService`, `IChatBroadcaster`, `IEchoHubClient`).
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
|
|
||||||
ASP.NET Core server -- controllers, hubs, authentication, and data access.
|
ASP.NET Core server -- controllers, hubs, ChatService, SignalRBroadcaster, authentication, and data access.
|
||||||
|
|
||||||
|
### Server.Irc
|
||||||
|
|
||||||
|
IRC protocol gateway -- TCP listener, command handler, IrcBroadcaster, and message formatter.
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ Articles related to the EchoHub server built with ASP.NET Core.
|
|||||||
|
|
||||||
- Authentication and JWT tokens
|
- Authentication and JWT tokens
|
||||||
- SignalR hub and real-time messaging
|
- SignalR hub and real-time messaging
|
||||||
|
- IRC gateway and protocol bridging
|
||||||
|
- ChatService and broadcaster pattern
|
||||||
- File upload and validation
|
- File upload and validation
|
||||||
- Rate limiting configuration
|
- Rate limiting configuration
|
||||||
- Database schema and migrations
|
- Database schema and migrations
|
||||||
|
|||||||
@@ -16,3 +16,7 @@
|
|||||||
href: ../_api_meta/server/toc.yml
|
href: ../_api_meta/server/toc.yml
|
||||||
- name: Articles
|
- name: Articles
|
||||||
href: server-articles/
|
href: server-articles/
|
||||||
|
- name: Server.Irc
|
||||||
|
items:
|
||||||
|
- name: API Reference
|
||||||
|
href: ../_api_meta/server-irc/toc.yml
|
||||||
|
|||||||
@@ -4,6 +4,16 @@
|
|||||||
|
|
||||||
EchoHub follows a decentralized model where each server is fully independent. There is no central authority or account federation. Users create one account per server.
|
EchoHub follows a decentralized model where each server is fully independent. There is no central authority or account federation. Users create one account per server.
|
||||||
|
|
||||||
|
The server exposes two protocol interfaces to the same chat backend:
|
||||||
|
|
||||||
|
```text
|
||||||
|
IRC Client ──► TCP :6667 ──► IrcGateway ──┐
|
||||||
|
├──► ChatService ──► DB + PresenceTracker
|
||||||
|
TUI Client ──► WebSocket ──► ChatHub ─────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Both protocols call into a shared `IChatService` for business logic. Events fan out to all registered `IChatBroadcaster` implementations (SignalR and IRC).
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
### EchoHub.Core
|
### EchoHub.Core
|
||||||
@@ -12,7 +22,7 @@ Shared library containing:
|
|||||||
|
|
||||||
- **Models**: `User`, `Channel`, `Message`, `RefreshToken`
|
- **Models**: `User`, `Channel`, `Message`, `RefreshToken`
|
||||||
- **DTOs**: Record types for API requests/responses
|
- **DTOs**: Record types for API requests/responses
|
||||||
- **Contracts**: `IEchoHubClient` -- the strongly-typed SignalR client interface
|
- **Contracts**: `IChatService` (protocol-agnostic chat operations), `IChatBroadcaster` (event fan-out interface), `IEchoHubClient` (SignalR client interface)
|
||||||
- **Constants**: `ValidationConstants` (shared regex patterns), `HubConstants`
|
- **Constants**: `ValidationConstants` (shared regex patterns), `HubConstants`
|
||||||
|
|
||||||
### EchoHub.Server
|
### EchoHub.Server
|
||||||
@@ -20,10 +30,21 @@ Shared library containing:
|
|||||||
ASP.NET Core web application:
|
ASP.NET Core web application:
|
||||||
|
|
||||||
- **Controllers**: REST API endpoints for auth, channels, users, files, server info
|
- **Controllers**: REST API endpoints for auth, channels, users, files, server info
|
||||||
- **Hubs**: SignalR `ChatHub` for real-time messaging
|
- **Hubs**: SignalR `ChatHub` -- thin adapter delegating to `IChatService`
|
||||||
- **Auth**: JWT token service (15-min access tokens, 30-day refresh tokens)
|
- **Auth**: JWT token service (15-min access tokens, 30-day refresh tokens)
|
||||||
- **Data**: EF Core with SQLite
|
- **Data**: EF Core with SQLite
|
||||||
- **Services**: Presence tracking, file storage, image-to-ASCII conversion
|
- **Services**: `ChatService` (core business logic), `SignalRBroadcaster`, presence tracking, file storage, image-to-ASCII conversion
|
||||||
|
|
||||||
|
### EchoHub.Server.Irc
|
||||||
|
|
||||||
|
IRC protocol gateway (separate project for clean separation of concerns):
|
||||||
|
|
||||||
|
- **IrcGatewayService**: `BackgroundService` with TCP listener on configured port(s), optional TLS
|
||||||
|
- **IrcCommandHandler**: Per-client IRC command dispatch -- handles `CAP`/`SASL`, `NICK`/`USER`/`PASS`, `JOIN`/`PART`/`PRIVMSG`/`QUIT`, `NAMES`/`TOPIC`/`WHO`/`WHOIS`/`AWAY`/`LIST`/`MODE`/`MOTD`
|
||||||
|
- **IrcBroadcaster**: `IChatBroadcaster` implementation that formats chat events as IRC protocol lines, with echo suppression (IRC convention)
|
||||||
|
- **IrcMessageFormatter**: Converts `MessageDto` to IRC `PRIVMSG` lines -- splits long text at word boundaries (~400 byte chunks), sends images as ASCII art line-by-line
|
||||||
|
|
||||||
|
IRC users authenticate with existing EchoHub accounts via `PASS`/`NICK`/`USER` or SASL PLAIN (BCrypt verification against the database).
|
||||||
|
|
||||||
### EchoHub.Client
|
### EchoHub.Client
|
||||||
|
|
||||||
@@ -31,11 +52,22 @@ Terminal.Gui v2 TUI application:
|
|||||||
|
|
||||||
- **UI**: Main window, dialogs, chat renderer with ANSI color support
|
- **UI**: Main window, dialogs, chat renderer with ANSI color support
|
||||||
- **Services**: API client with automatic token refresh, SignalR connection wrapper
|
- **Services**: API client with automatic token refresh, SignalR connection wrapper
|
||||||
- **Themes**: 6 built-in color themes
|
- **Themes**: 13 built-in color themes
|
||||||
- **Config**: Client configuration management
|
- **Config**: Client configuration management
|
||||||
|
|
||||||
## Communication
|
## Communication
|
||||||
|
|
||||||
- REST API for authentication, profile management, channel CRUD, file uploads
|
- **REST API** for authentication, profile management, channel CRUD, file uploads
|
||||||
- SignalR WebSocket for real-time messaging and presence updates
|
- **SignalR WebSocket** for real-time messaging and presence updates (TUI client)
|
||||||
|
- **IRC TCP** for real-time messaging via standard IRC protocol (IRC clients)
|
||||||
- JWT tokens passed via query string for SignalR authentication
|
- JWT tokens passed via query string for SignalR authentication
|
||||||
|
- IRC authentication via PASS/SASL PLAIN against BCrypt password hashes
|
||||||
|
|
||||||
|
## Broadcaster Pattern
|
||||||
|
|
||||||
|
The `IChatBroadcaster` interface allows multiple protocols to receive chat events:
|
||||||
|
|
||||||
|
- **SignalRBroadcaster**: Wraps `IHubContext<ChatHub>`, filters out IRC connections
|
||||||
|
- **IrcBroadcaster**: Iterates live IRC connections in a channel, formats events as IRC protocol lines
|
||||||
|
|
||||||
|
Both are registered in DI and called by `ChatService` when events occur. This means a message sent from an IRC client appears in the TUI client, and vice versa.
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
- [.NET 10 SDK](https://dotnet.microsoft.com/download)
|
- [.NET 10 SDK](https://dotnet.microsoft.com/download)
|
||||||
|
|
||||||
|
Or grab a self-contained binary from [Releases](https://github.com/HueByte/EchoHub/releases) -- no runtime needed.
|
||||||
|
|
||||||
## Run the Server
|
## Run the Server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -24,6 +26,37 @@ dotnet run --project src/EchoHub.Client
|
|||||||
|
|
||||||
Connect to a server, register an account, and start chatting.
|
Connect to a server, register an account, and start chatting.
|
||||||
|
|
||||||
|
## Connect via IRC
|
||||||
|
|
||||||
|
Enable the IRC gateway in the server's `appsettings.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Irc": {
|
||||||
|
"Enabled": true,
|
||||||
|
"Port": 6667
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then connect with any standard IRC client:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
irssi -c localhost -p 6667 -w <password> -n <username>
|
||||||
|
```
|
||||||
|
|
||||||
|
IRC users must have an existing EchoHub account. Authentication works via `PASS`/`NICK`/`USER` or SASL PLAIN. Messages flow bidirectionally between IRC and TUI clients.
|
||||||
|
|
||||||
|
For TLS, set `TlsEnabled: true`, `TlsPort: 6697`, and provide a PKCS#12 certificate path.
|
||||||
|
|
||||||
|
See the [Architecture](architecture.md) page for details on how the IRC gateway integrates with the chat service.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Server configuration is in `appsettings.json` (auto-generated on first run). See the [example config](https://github.com/HueByte/EchoHub/blob/master/src/EchoHub.Server/appsettings.example.json) for all available options.
|
||||||
|
|
||||||
|
To list your server on the [public directory](https://echohub.voidcube.cloud/servers), set `Server:PublicServer` to `true` and `Server:PublicHost` to your server's public address.
|
||||||
|
|
||||||
## Build from Source
|
## Build from Source
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ Release history for EchoHub.
|
|||||||
|
|
||||||
## Releases
|
## Releases
|
||||||
|
|
||||||
|
- [v0.2.0](v0.2.0.md) - IRC Gateway
|
||||||
- [v0.1.1](v0.1.1.md) - Directory Connection Self-Healing
|
- [v0.1.1](v0.1.1.md) - Directory Connection Self-Healing
|
||||||
- [v0.1.0](v0.1.0.md) - Initial Release
|
- [v0.1.0](v0.1.0.md) - Initial Release
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
- name: Overview
|
- name: Overview
|
||||||
href: index.md
|
href: index.md
|
||||||
|
- name: v0.2.0
|
||||||
|
href: v0.2.0.md
|
||||||
- name: v0.1.1
|
- name: v0.1.1
|
||||||
href: v0.1.1.md
|
href: v0.1.1.md
|
||||||
- name: v0.1.0
|
- name: v0.1.0
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# v0.2.0 - IRC Gateway
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **IRC protocol gateway** -- native IRC clients (irssi, WeeChat, HexChat, etc.) can connect to EchoHub servers
|
||||||
|
- **Cross-protocol messaging** -- messages flow bidirectionally between IRC and TUI clients in real time
|
||||||
|
- **SASL PLAIN authentication** -- IRC clients can authenticate via SASL or traditional PASS/NICK/USER
|
||||||
|
- **Full IRC command support** -- JOIN, PART, PRIVMSG, QUIT, NAMES, TOPIC, WHO, WHOIS, AWAY, LIST, MODE, MOTD
|
||||||
|
- **TLS support** -- optional encrypted IRC connections on port 6697
|
||||||
|
- **Image-to-IRC formatting** -- images appear as ASCII art line-by-line with download URLs
|
||||||
|
- **Message splitting** -- long messages automatically split at word boundaries (~400 byte chunks)
|
||||||
|
- **Configurable MOTD** -- server message of the day for IRC clients
|
||||||
|
|
||||||
|
## Architecture Changes
|
||||||
|
|
||||||
|
- Extracted shared business logic from `ChatHub` into protocol-agnostic `IChatService`
|
||||||
|
- Introduced `IChatBroadcaster` pattern for multi-protocol event fan-out
|
||||||
|
- `ChatHub` refactored to thin adapter delegating to `IChatService`
|
||||||
|
- `ChannelsController` updated to use `IChatService` for broadcasts
|
||||||
|
- New `EchoHub.Server.Irc` project for clean separation of concerns
|
||||||
|
- `IChatService` and `IChatBroadcaster` interfaces live in `EchoHub.Core/Contracts`
|
||||||
@@ -30,6 +30,16 @@
|
|||||||
],
|
],
|
||||||
"dest": "_api_meta/client",
|
"dest": "_api_meta/client",
|
||||||
"filter": "filterConfig.yml"
|
"filter": "filterConfig.yml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": [
|
||||||
|
{
|
||||||
|
"src": "../src/EchoHub.Server.Irc/bin/Release/net10.0",
|
||||||
|
"files": ["EchoHub.Server.Irc.dll"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dest": "_api_meta/server-irc",
|
||||||
|
"filter": "filterConfig.yml"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"build": {
|
"build": {
|
||||||
@@ -55,6 +65,12 @@
|
|||||||
"dest": "api/client",
|
"dest": "api/client",
|
||||||
"files": ["*.yml"],
|
"files": ["*.yml"],
|
||||||
"exclude": ["toc.yml"]
|
"exclude": ["toc.yml"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "_api_meta/server-irc",
|
||||||
|
"dest": "api/server-irc",
|
||||||
|
"files": ["*.yml"],
|
||||||
|
"exclude": ["toc.yml"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"resource": [
|
"resource": [
|
||||||
|
|||||||
+4
-2
@@ -4,11 +4,13 @@ _layout: landing
|
|||||||
|
|
||||||
# EchoHub Documentation
|
# EchoHub Documentation
|
||||||
|
|
||||||
Welcome to the EchoHub documentation. EchoHub is a decentralized, IRC-like chat application built with .NET 10 and SignalR.
|
Welcome to the EchoHub documentation. EchoHub is a decentralized, IRC-style chat platform. Self-hosted, terminal-first, with a built-in IRC gateway so native IRC clients can connect alongside the TUI client.
|
||||||
|
|
||||||
|
**Website:** [echohub.voidcube.cloud](https://echohub.voidcube.cloud/) | **Public Servers:** [Server Directory](https://echohub.voidcube.cloud/servers)
|
||||||
|
|
||||||
## Quick Links
|
## Quick Links
|
||||||
|
|
||||||
- [Getting Started](articles/getting-started.md) - Set up and run EchoHub
|
- [Getting Started](articles/getting-started.md) - Set up and run EchoHub
|
||||||
- [Architecture](articles/architecture.md) - Understand the system design
|
- [Architecture](articles/architecture.md) - System design and IRC gateway
|
||||||
- [API Reference](api/index.md) - Generated C# API documentation
|
- [API Reference](api/index.md) - Generated C# API documentation
|
||||||
- [Changelog](changelog/index.md) - Release history
|
- [Changelog](changelog/index.md) - Release history
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
# EchoHub nginx configuration example
|
||||||
|
#
|
||||||
|
# This config handles:
|
||||||
|
# - HTTPS reverse proxy for the HTTP API + SignalR WebSocket
|
||||||
|
# - TLS termination for IRC on port 6697
|
||||||
|
# - HTTP → HTTPS redirect
|
||||||
|
#
|
||||||
|
# Prerequisites:
|
||||||
|
# - EchoHub Server running on 127.0.0.1:5000
|
||||||
|
# - IRC gateway enabled on port 6667 (Irc:Enabled = true, Irc:TlsEnabled = false)
|
||||||
|
# - TLS certificate (e.g. from Let's Encrypt)
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# 1. Copy this file to /etc/nginx/sites-available/echohub
|
||||||
|
# 2. Replace "echohub.example.com" with your domain
|
||||||
|
# 3. Update certificate paths
|
||||||
|
# 4. ln -s /etc/nginx/sites-available/echohub /etc/nginx/sites-enabled/
|
||||||
|
# 5. nginx -t && systemctl reload nginx
|
||||||
|
#
|
||||||
|
# Note: The "stream" block for IRC TLS must go in the main nginx.conf
|
||||||
|
# (outside the http block), not in sites-available. See the bottom of
|
||||||
|
# this file for the stream config.
|
||||||
|
|
||||||
|
# --- Place this in /etc/nginx/sites-available/echohub ---
|
||||||
|
|
||||||
|
# HTTP → HTTPS redirect
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name echohub.example.com;
|
||||||
|
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
# HTTPS — API + SignalR WebSocket
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
server_name echohub.example.com;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/echohub.example.com/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/echohub.example.com/privkey.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
|
# File upload limit (match EchoHub's MaxFileSizeBytes)
|
||||||
|
client_max_body_size 10m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:5000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
# Standard proxy headers
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# Required for SignalR WebSocket upgrade
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $http_connection;
|
||||||
|
|
||||||
|
# Long timeout for WebSocket connections
|
||||||
|
proxy_read_timeout 86400s;
|
||||||
|
proxy_send_timeout 86400s;
|
||||||
|
|
||||||
|
# Disable buffering for real-time
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Place this in /etc/nginx/nginx.conf (outside the http block) ---
|
||||||
|
|
||||||
|
# IRC TLS termination (port 6697 → plain IRC on 6667)
|
||||||
|
# The stream module handles raw TCP, not HTTP.
|
||||||
|
#
|
||||||
|
# stream {
|
||||||
|
# upstream irc_backend {
|
||||||
|
# server 127.0.0.1:6667;
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# server {
|
||||||
|
# listen 6697 ssl;
|
||||||
|
# listen [::]:6697 ssl;
|
||||||
|
# proxy_pass irc_backend;
|
||||||
|
#
|
||||||
|
# ssl_certificate /etc/letsencrypt/live/echohub.example.com/fullchain.pem;
|
||||||
|
# ssl_certificate_key /etc/letsencrypt/live/echohub.example.com/privkey.pem;
|
||||||
|
# ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
#
|
||||||
|
# # Timeout for idle IRC connections (24 hours)
|
||||||
|
# proxy_timeout 86400s;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
Reference in New Issue
Block a user