# v0.2.14 | EchoHub Documentation

# v0.2.14

A reliability and security pass over end-to-end encrypted rooms: locked channels now offer the passphrase prompt instead of dead-ending on the "rejoin to unlock" placeholder, the client can no longer be tricked into sending plaintext into an encrypted room, and cached room keys are encrypted at rest instead of sitting in the config as base64. Ctrl+V grows up too — images copied from a browser or screenshot tool paste straight into the chat as attachments, and copying several files pastes them all into one message. Plus a set of IRC gateway fixes — decrypted image previews, display-name plumbing, and user/channel indicators.

## New Features

- Paste images straight from the clipboard — copy an image from a browser, a screenshot tool (Win+Shift+S), or an image editor and Ctrl+V it into the input: it's attached as a PNG (`image.png`), no saving to disk first, Discord-style. Transparency is preserved when the source provides PNG data; plain clipboard bitmaps are converted automatically. On Linux this uses `wl-paste`/`xclip`; on macOS it requires `pngpaste`. In end-to-end encrypted rooms pasted images go through the same client-side encryption as any other attachment.
- Multi-file paste — copying several files in your file manager and pasting attaches them all to a single message (up to the 10-attachment cap), staged as one batch alongside anything you type as the caption. Previously each pasted file was routed through its own `/send`, which could misbehave on large batches.
- Room keys encrypted at rest — the per-channel room keys cached so you don't retype a passphrase every launch are no longer stored as plain base64 in `config.json`. On Windows they're protected with DPAPI (current-user scope); on Linux/macOS with AES-GCM under a per-user key file created with `0600` permissions next to the config. Existing plain entries migrate to the encrypted format automatically on first load. The passphrase itself is never stored in any form.
- `[irc]` tag in the users panel — users online only through the IRC gateway are tagged `[irc]`, useful context since IRC clients lack encryption, attachments, and profiles. Someone also running the TUI shows untagged.
- `~` marker for private channels — the channel list now marks private (unlisted) channels with a trailing `~`, alongside the existing `*` for password-protected ones (`#room*~` when both apply).

## Bug Fixes

- Locked encrypted channels now prompt for the passphrase. Auto-joining your channels at connect silently entered end-to-end encrypted rooms you're a member of without running the unlock flow — on a new device (or after a cancelled prompt) the room showed only `[encrypted — rejoin this channel with its passphrase to unlock]` placeholders, and only a manual `/join` recovered it. Selecting the channel now offers the passphrase prompt; entering it unlocks history and live messages in place. Cancelling is remembered for the session so reselecting the channel doesn't nag — `/join` or trying to send always re-offers the prompt.
- A stale cached room key no longer beats a fresh one. If an encrypted channel was deleted and recreated under the same name, a client that still had the old key cached kept encrypting messages nobody else could read. Typing the passphrase on join now always adopts the key from the server's current envelope, replacing the stale cache.
- IRC clients no longer get flooded with ciphertext for image messages. The gateway forwarded image ASCII previews without stripping transport encryption, spamming IRC clients with one enormous `$ENC$v1$…` line per image. Previews are now decrypted before formatting, and any that still can't be read (e.g. end-to-end room ciphertext the server cannot decrypt) are skipped in favor of the plain `[Image: name] url` line.
- Display names now show on chat messages. Messages only carried the sender's username, so a configured display name appeared in the user list but not on the messages themselves. Live messages, history, and attachment messages now all carry it; mention and profile lookups stay keyed to the username.

## Security

- No plaintext can leak into an encrypted room. Previously, a client without the room key silently sent unencrypted text into an end-to-end encrypted channel (and other members saw it as a normal message, none the wiser it went over the wire readable by the server). All send paths — typed messages, staged file attachments, and URL sends — are now blocked while a room is locked: the client offers the unlock prompt, keeps staged files in the tray, and refuses to transmit until the key is present, with a hard guard at the connection layer as backstop.