Skip to content

Releases: Plainwire-development/Plainwire

Plainwire 2.8.0

Choose a tag to compare

@RobertFlexx RobertFlexx released this 03 Oct 22:03

Plainwire 2.8.0

DM encryption and individual locks

  • Add a separate DM-wide encryption setting and individual message locks. Set up the shared key with DM-wide encryption off, lock selected outgoing text, or lock your existing text messages.
  • Require both people to approve turning DM-wide encryption off. Keep existing history encrypted and retain the shared key/fingerprint. Either participant can turn encryption on again.
  • Let only the sender explicitly remove a selected message's lock after DM encryption is off. Confirm the resulting disclosure to the relay. Ordinary edits cannot reveal encrypted text, and stale changes are rejected.
  • Add persistent device locking, saved-key unlocking without retyping, and synchronization between tabs for the same account/browser profile. Clear memory caches across account changes and guard asynchronous crypto work against device/account changes.

Encryption engine and private embeds

  • Send v2 AES-256-GCM envelopes with a fresh authenticated message nonce and IV. Preserve identity during edits and reserve each nonce to a single stored message, including after unlock/relock and soft deletion. Existing 2.7.0 encrypted history remains readable.
  • Require the current encryption policy revision on DM text posts/edits once a key is registered. Ignore stale policy events and pin observed revisions/fingerprints on devices.
  • Render Markdown and local link cards under decrypted text, including actively encrypted DMs. Direct GIF/image/audio/video links and YouTube/Vimeo players load only when the reader chooses; private URLs do not go through the preview API or media proxy.
  • Enable the GIF picker in encrypted chats. Explain that GIF searches contact the relay/provider; selected GIF URLs are encrypted when sent. Permit direct HTTPS media in the page CSP while keeping scripts and general networking restricted to the same origin.
  • Keep encrypted text out of navigation previews and avoid automatic media/voice-note enhancement of private links. Add lock actions to message menus and keyboard-accessible message toolbars; preserve mobile touch targets and short-viewport composer layout.

Migration 56 adds encryption policy revisions, disable requests, and the nonce registry. It preserves active 2.7.0 encrypted DMs. Migration 57 widens the upload backfill cursor to accept 64-bit message IDs; the database pool also replaces dead connections after unexpected client failures without automatically replaying writes. Upgrade backend and frontend together; older clients must refresh before writing to DMs that have an encryption key.

This remains manually exchanged shared-key text encryption, with no forward secrecy or independent cryptographic audit. Uploaded files, calls, metadata, and remote media bytes are outside this mode. Device locking is not a password-protected vault. Read setup and limitations and the review record.

Validation

make package passed with 290 backend tests against PostgreSQL and the full browser, security, encrypted DM, responsive settings, reporting/admin, real WebRTC media, audio, and call-health suites. The seven-language SDK checks and Go race detector passed. The 250-user realtime smoke, live HTTP/WebSocket load-harness self-test, and pinned Gleam model checks passed. npm's advisory audit reported zero known vulnerabilities in the locked application dependencies. The extracted source archive passed source verification. The extracted runtime archive passed a real PostgreSQL/HTTP test covering startup, migrations, AES-GCM messages, stale revisions, disable consent, sender-only lock removal, preserved history, nonce reuse rejection, and healthy database connections after the backfill interval.

Source and Linux x86_64 OTP runtime archives include SHA-256 checksums. The runtime was built without the optional native call-health worker and Scylla native driver; those features require their documented native builds.

Plainwire 2.7.0

Choose a tag to compare

@RobertFlexx RobertFlexx released this 03 Oct 04:43

Plainwire 2.7.0

Encrypted private text

  • Add explicitly enabled end-to-end encrypted text for accepted two-person human DMs. Keys are generated/imported on the browser and exchanged through a trusted external channel. The relay receives ciphertext and a fingerprint, never the raw key.
  • Lock encrypted DMs against plaintext posts/edits/forwards, key replacement, and added members. Missing keys and authentication failures show unavailable text. Links remain literal text, encrypted messages cannot be forwarded, and uploads/GIFs/voice notes are disabled for this mode.
  • Add migration 55 for the locked DM fingerprint. Existing conversations, server channels, bots, group DMs, forums, and calls retain their features.
  • Read setup and limitations before enabling: this mode covers new text only, uses manual shared-key exchange, and has no forward secrecy or independent cryptographic audit. Earlier messages, files, calls, and metadata are outside it.

Security and correctness

  • Fail new at-rest writes when a configured encryption key is invalid or a production key is missing. Malformed encrypted content is never passed through as plaintext.
  • Disable native Erlang distribution and EPMD in shipped VM arguments and reject unsafe named production runtimes. Manage release lifecycle through systemd/OpenRC; remote Erlang RPC commands are disabled.
  • Include the required load-tool sources in portable source archives and exclude generated build trees. Pin Rust SDK and Gleam load-model dependency resolutions.
  • Load optional native drivers on demand so a PostgreSQL release starts even when the Scylla driver was not built.
  • Validate full UTF-8 message sizes and preserve encrypted envelope integrity. Keep ciphertext out of navigation previews/search tokens and private content out of browser API/signaling debug logs.
  • Guard call signaling across room/peer replacement, queue local candidates until matching descriptions are sent, and resend duplicate answers only for matching SDP.
  • When relay configuration is unavailable or expired, fail closed instead of contacting a public STUN service or exposing direct candidates before the server's privacy policy is known.

Mobile and bot SDKs

  • Increase mobile message spacing, make composer actions 44px touch targets, and keep typing at 16px to avoid automatic zoom. Improve the encrypted key dialog on narrow screens.
  • Add Discord-style JavaScript command interactions with typed options, explicit defer/reply/fail, and one final reply. Keep existing returned-string handlers compatible.
  • Bound response streaming and request timeouts, respect Retry-After for explicit JavaScript rate-limit rejections, refuse normalized API-path escapes and inherited handlers, cap claimed work to concurrency, and renew active JS/Python/Go leases.
  • Keep worker exception details in local error hooks and close Python responses reliably. Server bot rate-limit responses now include Retry-After.

See the review record and SDK READMEs for details.

Validation

make package passed with 285 backend tests against PostgreSQL and the full browser, security, encrypted DM, responsive settings, reporting/admin, real WebRTC media, audio, and call-health suites. The seven-language SDK checks and Go race detector passed. The 250-user realtime smoke, live HTTP/WebSocket load-harness self-test, and CI-pinned Gleam model checks passed. npm's current advisory audit reported zero known vulnerabilities in the locked application dependencies. The extracted source archive passed source verification. The final packaged server passed a real PostgreSQL/HTTP startup and encrypted-DM enforcement smoke test. Source and Linux x86_64 OTP runtime archives include SHA-256 checksums; the runtime was built without the optional native call-health worker and Scylla native driver.

Plainwire 2.6.5-1

Choose a tag to compare

@RobertFlexx RobertFlexx released this 01 Oct 10:58

Plainwire 2.6.5-1

Report queue visibility

  • Fixed reports appearing to be missing when the reporting user and signed-in admin are the same account. Owners and operators now see their own submissions as clearly marked, read-only cases.
  • Own cases expose submitted reasons and screenshots, status, and public responses. Internal notes, reviewer assignment, priority, resolution codes, and message context remain private. Priority and assignment filters exclude own cases to prevent inference of hidden review metadata.
  • Another owner or operator must review the case. Backend guards still reject all own-case review edits and linked account restrictions. Reports about the signed-in reviewer remain hidden, and viewers cannot open reports.

Queue refresh

  • The visible Reports view now checks for updates every five seconds, including while a case or filter field is open. Updates preserve draft notes, open dialogs, and unapplied filter text.
  • Added Refresh reports for an immediate check. Temporary refresh failures retain the current queue, display a retry message, and retry automatically. Filters and older-page cursors still apply.
  • Submission already saves the report before returning success; this patch fixes visibility and queue refresh. It does not require another database migration beyond migration 54.

Validation

make check passed, including 269 backend tests with real PostgreSQL and the full browser, security, responsive-layout, admin moderation, and WebRTC suites. Reporting regressions cover own-submission visibility, private-field isolation, filter inference prevention, own-case mutation and linked-action rejection, subject exclusion, reviewer access, and screenshot authorization. Browser regressions cover new submissions arriving with focused filters and open note drafts, refresh failure recovery, same-account read-only cases, reviewer workflows, and viewer isolation, alongside the existing full release suite.

Plainwire 2.6.5

Choose a tag to compare

@RobertFlexx RobertFlexx released this 01 Oct 10:12

Plainwire 2.6.5

Profile reporting and evidence controls

  • Choose Report user on a full profile or server profile, including blocked accounts. Your own profile offers My reports.
  • Paste PNG/JPEG screenshots into the report form, preview them, and remove individual screenshots before submitting. Invalid additions preserve the current selection.
  • Reporting retains the existing backend permissions, evidence validation, case workflow, retry keys, and private review boundaries. No new database migration is needed beyond migration 54.

Call window fixes

  • Fixed mouse-first resizing followed by minimizing leaving a giant call bar. The observer now tracks the live Elm body, and expanded dimensions no longer apply to the reused compact element.
  • Added Reset window beside audio tools. Keyboard resizing, saved dimensions, viewport bounds, and desktop position restoration remain available.
  • Hiding and showing a shared screen preserves its expanded height, including viewport changes while hidden.
  • Desktop call controls remain accessible over overlapping shared-screen windows; dialogs and context menus appear above call windows.
  • Switching to a phone layout preserves desktop preferences. Position updates avoid mutation feedback loops, and drag click suppression expires immediately after the gesture.

Security and moderation reliability

  • Private attachments require revalidation before browser cache reuse and vary by session cookie. File authorization still runs before conditional, range, and HEAD responses. Previously downloaded or cached copies cannot be recalled.
  • Admin authentication requests disable caching and have a timeout. Session changes reject late responses; expiry clears account/case content and dialogs.
  • Delayed account/server details cannot reopen dismissed dialogs. Every admin view checks its request generation before rendering, preventing old lists or searches from overwriting the selected view. Admin modal backgrounds are inert.
  • Upload authentication outages return retryable HTTP 503 instead of telling clients they are unauthenticated.
  • Reported account IDs outside PostgreSQL's integer range are rejected before database work; 64-bit message IDs remain supported.

Validation

Release validation runs make check, including the real PostgreSQL authorization/reporting tests, real HTTP private-download tests, browser/security/reporting/moderation regressions, responsive settings, and real WebRTC audio/video tests. CI also exercises the load harness and Gleam scalability model before source archive construction. The new mouse-first regression failed on the previous implementation.

See the audit record for scope, fixes, and remaining limits.

Plainwire 2.6.4-1: Reporting and moderation

Choose a tag to compare

@RobertFlexx RobertFlexx released this 01 Oct 08:17

Plainwire 2.6.4-1

2.6.4-1 adds user reports with screenshot evidence and an admin moderation case workflow. It includes PostgreSQL migration 54, applied automatically at startup. Installs on 2.6.4 can upgrade directly; no additional service is required.

Reporting

  • Report a person or message from its context menu, including touch press-and-hold. Select a category and provide a reason, up to three PNG/JPEG screenshots, or both. Screenshots show previews and are limited to 5 MiB each.
  • Sharing a message is an explicit, unchecked option. The backend verifies access and the reported author and copies only that message. Normal conversations remain unavailable to admin operational views.
  • My reports tracks case status and public reviewer responses and allows withdrawing active cases. Uploads stay out of the chat composer and preserve drafts. Retry keys prevent duplicate cases after ambiguous network failures.

Moderation cases

  • Owners and operators get a report queue with both identities, status/priority/assignment filters, username search, bounded pagination, screenshots, optional message context, and case history. Viewers cannot access reports.
  • Reviewers can assign cases, set priority, write internal notes, resolve, dismiss, and reopen decisions. Internal notes and reviewer assignments remain private. Conflicts of interest exclude cases filed by or about the current reviewer; revision checks reject stale edits.
  • Linked suspend, ban, and disable actions resolve the case atomically with the account restriction and session revocation. Existing account protections remain enforced. Reports do not automatically restrict accounts.
  • Reasons, message snapshots, review notes, custom reporter responses, and screenshot copies honor the configured content encryption key. Evidence copies survive deletion of the original upload and are accessible only from case-scoped authenticated endpoints.
  • Submission limits and transactional storage budgets bound abuse. Closed-case screenshots and message snapshots expire after 90 days by default, with configurable retention and a bounded background sweep. Case reasons and review history remain. Default screenshot storage is 32 MiB per reporter and 512 MiB instance-wide, including encryption overhead.

Validation

Validation passed make check with 267 backend tests, including executable PostgreSQL authorization, rollback, encryption, retention, pagination, and quota regressions. Reporting browser workflows and existing UI, security, responsive admin/settings, and real WebRTC tests all passed. GitHub CI now runs the PostgreSQL-backed tests as well as reporting browser regressions. The portable source archive and its SHA-256 checksum are verified before publication.

See reporting and moderation and admin operations for workflows, privacy boundaries, retention, configuration, and API details.

Plainwire 2.6.4

Choose a tag to compare

@RobertFlexx RobertFlexx released this 01 Oct 05:28

Plainwire 2.6.4

2.6.4 adds targeted ringing for active group calls and strengthens invitation lifecycle and media regressions. It adds no database migrations or production environment variables. Installs on 2.6.3 can upgrade directly.

Group call invitations

  • While connected to a group call, right-click an absent member in the People list and choose Ring to call. Touch screens support pressing and holding the member row. Self, blocked users and members already in the call have no ring action.
  • The invited member sees who rang them and the group name, with Accept and Decline controls. Their microphone stays off until they accept. The sender sees a pending ringing badge and cannot repeatedly click the action while it is pending.
  • Accepting adds the member to the existing call. Declining, expiration, disconnecting, losing group access, or the caller leaving clears only the invitation and preserves the ongoing call.
  • The backend checks both accounts and accepted group membership, blocks in either direction, caller socket ownership, recipient availability and room capacity. Database failures deny invitations. Bot accounts cannot ring or be rung.
  • Invitations use recipient-bound, expiring random tokens. Duplicate requests preserve the original token and deadline. Stale accepts, declines and timers cannot affect a newer invitation. Accepting in one tab dismisses the popup in the other tabs without joining them.
  • A caller can ring a given member once per 30 seconds, and a member can receive at most three new targeted invitations per minute across callers. Existing call timeout and participant-capacity settings apply. Offline or busy members are not queued for later ringing.

Validation

New executable backend regressions cover authorization against PostgreSQL, malformed and forged tokens, socket handoffs, disconnect and access revocation, capacity changes during ringing, duplicate tabs, stale timers and shared recipient rate limits.

The real WebRTC browser suite now exercises three-person group calls, desktop and mobile member menus, microphone privacy before acceptance, decline and timeout isolation, stale notification handling, and bidirectional audio on every peer connection. The original connection and microphone remain live when another member accepts. RTC audio-volume checks continue to measure actual media duration to tolerate cached browser statistics.

Validation passed make check with 250 backend tests, including the PostgreSQL regressions, frontend and backend compilation, source contracts, browser UI/security tests, responsive settings, admin actions and the complete real WebRTC suite. GitHub CI and the portable source archive are checked before publication. Source downloads include SHA-256 checksums. No additional deployment configuration is required. See group call invitations for behavior and protocol details.

Plainwire 2.6.3

Choose a tag to compare

@RobertFlexx RobertFlexx released this 01 Oct 03:23

Plainwire 2.6.3

2.6.3 fixes attachment authorization, authentication and account recovery, client plugin isolation, and UI state bugs found during the security audit. It adds no database migrations or production environment variables. Installs on 2.6.2 can upgrade directly.

Release build fix

Republished from commit d06f904 with the RTC release-check fix and the latest pinned dependencies and OTP 29 cleanup. Audio checks now wait for advancing media samples, discard transition audio, and verify normalized power instead of relying on 300 ms sleeps. make check passed on Node 20.19.2, including real RTP tests and all 218 backend tests.

Security and account recovery

  • Posting a known upload ID can no longer grant access to an unreadable file. Posts, edits, forwards, threads and replies check that every referenced upload is ready and currently readable by the author. Channel edits and forwards also enforce attachment and voice-note permissions.
  • Both normal and host-admin JSON APIs require Content-Type: application/json, including optional charset parameters. Requests with a missing or different media type receive HTTP 415. This closes form-based login CSRF; custom API clients must send the JSON content type.
  • JSON request limits count every received byte, including the final body chunk, preventing oversized complete requests from bypassing the configured limit.
  • Password reset validates the new password before claiming the link, and commits the token claim, password change and session revocation together. A database failure leaves the link usable for a retry.
  • Password changes revoke outstanding reset links and host-admin sessions. Reset revokes all ordinary and host-admin sessions. Changing or removing a recovery email revokes old links, and reset rechecks the current verified address and account eligibility.
  • Email verification, replacement and removal update account and token state in one transaction, with cache invalidation after commit.

Plugins and UI

  • Client plugins use a worker with its own enforced Content Security Policy. Direct networking, script imports and nested workers remain blocked even if a plugin restores browser globals. API writes still require an explicit grant, and encoded path traversal is rejected.
  • Saved plugins start after authentication, preserve worker state during periodic reconciliation, and stop on logout. A theme compiler failure does not block plugins.
  • Loading another person's profile no longer overwrites the bridge's signed-in identity used by moderation, typing and calls.
  • Delayed server, thread, profile, forum-list and bot-command responses cannot replace another active view. Closing a member-profile dialog keeps it closed when its response arrives.
  • Late bot-command acknowledgements clear only the submitted draft. New text and drafts in another channel are preserved, and duplicate in-flight submissions are suppressed.
  • Bridge dialogs have accessible names, keyboard focus trapping, Escape dismissal and focus restoration. Their overlays stay outside Elm's managed body children.
  • Incremental frontend builds now track nested Elm view modules. Documentation and current-version references are consistent.

Validation and upgrade notes

The audit passed 218 backend tests, including PostgreSQL recovery and attachment regressions, plus frontend/backend builds, browser security and UI tests, responsive settings, admin actions, and real WebRTC/RTP tests. The browser security suite now runs in GitHub CI.

Existing attachment references are preserved. The fix prevents new unauthorized sharing grants; historical grants need deployment-specific review. Optional live Redis, Scylla, Partisan, external TURN and native Fortran integration were not exercised during this audit.

See the audit report for findings, regression evidence and testing limits. Published source archives contain authoritative inputs; run the documented build on the deployment host to generate frontend assets and the runtime release.

v2.6.2

Choose a tag to compare

@RobertFlexx RobertFlexx released this 30 Sep 06:26
Release 2.6.2: finish the message search backfill

Version bump and release notes for the search index fix in e378c7c. No
database migration and no new environment variables.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Plainwire 2.6.1

Choose a tag to compare

@RobertFlexx RobertFlexx released this 30 Sep 05:28

Plainwire 2.6.1

2.6.1 improves browser call recovery and screen sharing. It carries no database
migration and no new environment variables. Installs on 2.6.0 can upgrade
directly.

Calls and reconnects

  • Recover pending call starts, joins, and answers after signaling reconnects,
    while discarding signals queued for a previous connection.
  • Prevent overlapping room updates from leaving a call stuck until a page
    refresh.
  • Recover microphone capture when a device disconnects or a processed audio
    track ends. Retry capture with a bounded delay, fall back to the default
    microphone when needed, and resume after device or connectivity changes.
  • Repair peer connections when changing screen or microphone tracks fails, so
    screen video and available system audio can resume without reloading.

Mobile and regression coverage

Call controls recover through mobile foreground and connectivity changes.
Browser regressions now exercise real two-participant media, signaling loss,
microphone disconnects, screen audio, and rollback paths.

Screen audio availability still depends on the browser, operating system, and
the source selected in the share picker.

Plainwire 2.6.0

Choose a tag to compare

@RobertFlexx RobertFlexx released this 23 Sep 21:37

Plainwire 2.6.0

2.6.0 adds live Mac app presence metadata for native clients. It carries no
database migration and no new environment variables. Installs on 2.5.8 can
upgrade directly.

Mac app presence

Authenticated WebSocket connections from Plainwire for Mac identify their
platform. Presence snapshots now include a platforms map, and online/status
events include client_platform when a visible Mac app session exists. The
platform clears when that session disconnects or becomes invisible, even if
the same account remains online in a browser.

Presence remains scoped to visible sessions. Redis-backed multi-node installs
share the Mac indicator with the same expiry behavior as presence status.
Browser and bot sessions are unmarked, and existing clients can ignore the
new fields.