Skip to content

Releases: donaldsteele/bubbles

bubbles v0.3.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 22:10

bubbles v0.3.0

Pairing that apps can manage themselves: reconnect as the same app, disconnect for real, cancel a request, and see the channels the bot is in.

What's new

  • Reconnect instead of a second app. An app that was paired before can name itself in its new pairing request. The admin sees "Replaces (@username)" and a "Reconnect as the existing app" box, ticked by default.
    • The app keeps its bot, its username and its channels.
    • Its old tokens stop working when it collects the new one.
    • Pairing netdiag again no longer creates netdiag-2.
  • Disconnect. An app can revoke its own token. The next request with that token gets 401.
  • Cancel. An app can withdraw a pairing request it no longer wants. If the request was already approved but not collected, the new app is disabled.
  • Channels in the pairing answer. The answer that carries the token also lists the channels the bot is in, so the app knows where to post.
  • Approval form:
    • "Also create a channel for this app" starts ticked when the app asks for alerts:write and no channel has that name yet.
    • An existing public #<username>-alerts channel is reused.
    • A warning shows when an alerts app would end up in no channel.
    • Archived channels are no longer offered.
  • Docs:
    • docs/netdiag.md now describes what netdiag v0.6 sends: severities, dedupe keys and the "Fixed at …" resolve note.
    • The scopes table is fixed: listing alerts needs messages:read.

Security notes

  • Anyone who can reach the onboarding port can open a pairing request that names any app id. The request alone grants nothing. A reconnect is only as safe as the admin's check: compare the six-digit code and the CA fingerprint as for a new pairing, and deny a reconnect you did not expect.
  • An enabled app's old tokens are revoked only when it collects the new token. An unclaimed or cancelled reconnect leaves them working. Reconnecting a disabled app revokes its old tokens at the approval itself.
  • Cancelling needs the request's poll secret. A wrong one gets 404, like the poll, and cancels share the poll rate limit (2 per second, burst 20, per IP).
  • Self-revoke needs the token itself and ends only that token.

Upgrading from v0.2.x

  • Migration 0004 rebuilds pairing_requests. Every row is kept. It adds the cancelled state, replaces_app_id and replaced.
  • As with earlier migrations, the server first saves the database to backups/pre-migrate-3-4.db.
  • After the upgrade, a v0.2.x binary refuses to open the database ("database schema version 4 is newer than this binary supports"). To go back, restore that backup.
  • Apps built with the new Go SDK still pair with a v0.2.x server. The SDK leaves out replaces_app_id when the server refuses it. Cancel and self-revoke need v0.3.0.

API changes

  • Added:
    • DELETE /api/v1/apps/self/token
    • DELETE /api/v1/pairing/requests/{id} (with X-Poll-Secret)
  • Changed:
    • POST /api/v1/pairing/requests takes replaces_app_id.
    • The pairing poll answer that carries the token has channels: [{id, name}].
    • The pairing state can be cancelled.
    • The admin pending-pairing listing has replaces.
    • The admin approve request takes replace_app.
    • See docs/openapi.yaml.
  • Go SDK (pkg/bubblesclient):
    • Pairing.Channels()
    • Pairing.Cancel()
    • Pairing.ID()
    • Client.RevokeSelf()
    • ErrPairingCancelled

Downloads

  • Same file layout as v0.2.0, with v0.3.0 in the file names.
  • Docker: ghcr.io/donaldsteele/bubbles:v0.3.0

Field testing still pending

  • Real phones.
  • Tray app on macOS and Linux.
  • Reconnect, disconnect and cancel from netdiag: netdiag v0.6.0 does not use these APIs yet.
  • See docs/field-checklist.md.

bubbles v0.2.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 00:21

bubbles v0.2.0

Easy onboarding: people create their own accounts, the tray app finds the server, and there is no setup wizard.

What's new

  • The admin password is generated on first start. It is printed in the console (and docker logs) and saved to admin-password.txt.
  • Self sign-up asks for one "Your name" field. The @handle is made automatically. People sign in with their name or their handle.
  • Sign-up opens for 24 hours after first start or factory reset, then closes by itself. Admins can reopen, close, or change the window in Admin > Settings > Sign-up.
  • Admin > Add person creates an account directly.
  • Tray app: Join buttons for bubbles servers found on the network. Confirm the server, the app installs its certificate, then you choose Create account or Sign in.
  • The tray app refuses certificates that are not limited to the local network.
  • The phone onboarding page has a "Create your account" button.
  • Any password works. The server does not enforce password strength.

Security notes

  • Open sign-up is meant for a trusted LAN. Anyone who can reach the server can create an account while sign-up is open.
  • Weak passwords are allowed.
  • The admin password is visible in the console and docker logs, and in the owner-only admin-password.txt, until you change it.
  • Rate limits:
    • Login: 5 attempts per account and 20 per IP per 15 minutes.
    • Sign-up: 20 per IP per hour.
  • To lock down a server:
    • Close sign-up in Admin > Settings > Sign-up.
    • Use invites for new people.
    • Change the admin password.

Upgrading from v0.1.x

  • Sign-up stays closed after an upgrade. Migration 0003 stores open_registration=false on any server that already has users and no stored sign-up setting. Upgraded servers stay invite-only, as they were before.
  • To open sign-up on an upgraded server, an admin turns it on in Admin > Settings > Sign-up. Opening it starts the 24-hour window (or the window length the admin sets).
  • New servers and factory-reset servers open sign-up for 24 hours.
  • Existing users keep their usernames.
  • Display names must be unique only for new registrations and renames.
  • Migration 0002 adds users.display_key.

API changes

  • Removed:
    • GET /api/v1/setup/status
    • POST /api/v1/setup
  • Added:
    • GET /api/v1/status
    • POST /api/v1/auth/device-register
    • POST /api/v1/admin/users
    • POST /api/v1/admin/registration
  • Changed:
    • POST /api/v1/register takes {name, password} only.
    • Invite accept takes {name, password}. The legacy username and display_name fields are still accepted.
    • The FactoryReset response replaces setup_token and setup_url with admin_username, admin_password, and sign_in_url.
    • AdminSettings adds registration_window_hours, open_registration_until (read-only), and registration_open.
    • ServerStatus has new fields. See docs/openapi.yaml.

Downloads

  • Same file layout as v0.1.1, with v0.2.0 in the file names.
  • Docker: ghcr.io/donaldsteele/bubbles:v0.2.0

Field testing still pending

  • Real phones.
  • Tray app on macOS and Linux.
  • See docs/field-checklist.md.

bubbles v0.1.1

Choose a tag to compare

@github-actions github-actions released this 12 Oct 18:58

Bug-fix release.

Fixes

  • Unread badge on the open channel. Unread counts include thread replies, but opening a channel only marked messages read up to the newest message in the channel list. A thread reply posted after that message stayed unread, so the badge never cleared, even with the channel open. Opening a channel now also marks those replies read, and a reply that arrives while you are reading clears at once. Replies that arrive while you are in another channel now raise its badge right away; before, they appeared only after a reload.
  • Channel header on phones. The header used to wrap over four rows and take about a third of the screen. It is now one row next to the menu button, with the title, a Channel settings button, pins and members. The member count and the notification, alert and mute choices open on a second row from Channel settings. Header buttons are touch-sized on phones. Desktop is unchanged.

API notes

  • POST /channels/{id}/read: when nothing after the given message would count as unread except thread replies, the read marker moves past the channel's newest message. last_read_id can therefore be the id of a thread reply.
  • GET /channels/{id}/messages?around=<id>: a thread reply's id now centres the page on the newest root at or before it, instead of returning 404.

Downloads

Same files as v0.1.0, with v0.1.1 in the names. The Docker image is ghcr.io/donaldsteele/bubbles:v0.1.1 (also :latest). Check zips against SHA256SUMS. See the v0.1.0 notes for first-time setup.

Full changes: v0.1.0...v0.1.1

bubbles v0.1.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 17:05

First release of bubbles: secure chat for a local network. One server binary runs on any LAN host. Phones and computers join through the web app, or through the desktop tray app. It needs no internet connection and no cloud account.

Project site and screenshot tour: https://donaldsteele.github.io/bubbles/

What's in it

  • Chat: public and private channels, DMs and group DMs, threads, reactions, mentions, pins, search, unread counts, drafts that sync across devices, presence and typing.
  • Files: upload by button, drag and drop or paste. Images, video and audio show inline. EXIF location data is removed from photos.
  • Alerts: severity and acknowledgement, incoming webhooks (native JSON and a Slack-compatible subset), app tokens, a Go SDK (pkg/bubblesclient) and an MCP server for agents. netdiag can post its alerts here.
  • Admin: invitations with roles, an audit log, encrypted backups, TLS and CA management. Clear content and Factory reset let you reuse the server at the next LAN party.
  • Security: all app traffic is HTTPS with a certificate from a local CA that each device trusts once. There is no end-to-end encryption: the server can read messages. docs/security.md explains the threat model.

Downloads

What File
Server, Windows bubbles-v0.1.0-windows-amd64.zip, bubbles-v0.1.0-windows-arm64.zip
Server, macOS bubbles-v0.1.0-darwin-arm64.zip (Apple silicon), bubbles-v0.1.0-darwin-amd64.zip (Intel)
Server, Linux bubbles-v0.1.0-linux-amd64.zip, bubbles-v0.1.0-linux-arm64.zip (Raspberry Pi with a 64-bit OS)
Tray app (optional desktop client) bubbles-tray_v0.1.0_windows_amd64.zip, bubbles-tray_v0.1.0_macos_arm64.zip, bubbles-tray_v0.1.0_linux_amd64.zip
Docker (linux/amd64, linux/arm64) docker pull ghcr.io/donaldsteele/bubbles:v0.1.0

Check a server download against SHA256SUMS:

sha256sum --check --ignore-missing SHA256SUMS      # Linux
shasum -a 256 --check --ignore-missing SHA256SUMS  # macOS

Each tray zip has its own .sha256 file.

Getting started

  1. Unzip the server and run bubbles on a computer that stays on your network.
  2. The console prints a setup token and addresses such as https://192.168.1.20:28225. Open one in a browser on that computer and create the admin account.
  3. To add another device, open the onboarding page on port 28226 (for example http://192.168.1.20:28226). Install the local CA once, then scan the QR code.

The default ports are 28225 (HTTPS) and 28226 (onboarding). You can change them with --https-addr and --http-addr.

The binaries are not code-signed, so Windows SmartScreen and macOS Gatekeeper warn the first time you run them. HOW-TO-OPEN.txt in each zip shows how to get past the warning. The macOS tray app is ad-hoc signed only.

Known limitations

  • This is a first release. CI tests every build on Windows, macOS and Linux, including browser tests in Chromium, Firefox and WebKit. Testing on real devices, such as phones, Web Push, mDNS on mixed networks and the tray app on macOS and Linux, is still in progress. docs/field-checklist.md has the list.
  • On SSDs, a reset does not guarantee that deleted data is unrecoverable. docs/security.md explains why.

Bug reports and feedback: https://github.com/donaldsteele/bubbles/issues