Repository navigation
Conversation
Keeps this fork's bootstrap pinned to the installer in the same checkout. Original bootstrap by Sean Heiney (Awassee/wolfbbs). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Back up .env before it is overwritten or amended (only when it changes) - Require typing WIPE to overwrite .env, delete data volumes, or remove the install directory; --yes no longer auto-confirms these (use --i-understand-data-loss for automation) - Default the bare-run menu to Status when a WolfBBS stack is running Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…t-in - Publish all ports on WOLFBBS_BIND_ADDR (default 127.0.0.1) so a local reverse proxy/tunnel cannot be bypassed from the LAN - restart: unless-stopped on every service so the board survives reboots - Move the bbs Docker socket and host mounts to docker-compose.app-upgrade.yml, layered in by the installer only when WOLFBBS_ENABLE_APP_UPGRADE=true - Document network exposure, restarts, and in-BBS upgrades in INSTALL.md Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Callers set a recovery email in /settings, confirmed by a 24h single-use link; password resets go to the confirmed address - The board host, its parent domain, and WOLFBBS_RECOVERY_EMAIL_BLOCKED_DOMAINS are refused as recovery addresses and never used as reset recipients - deploy/cloudflare-email-worker: Email Routing Worker that posts inbound mail to wolfbbs-mailin through a tunnel, bouncing unknown handles - Docs for free inbound (Email Routing) and outbound (free SMTP relay) setup Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Read-only mode blocked every admin save, including the toggle that turns it off, so the only recovery was editing the database and restarting web. - Add an exit_read_only action (admin role + CSRF) that is allowed while read-only is on, with a banner button on /admin/config and an audit entry - Point the 403 message at /admin/config - Document the button and the database fallback in admin.md and TROUBLESHOOTING.md Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…olors The old stylesheet layered several theme and accent modes, saved per browser, over hard-coded light-theme colors. Browsers on different saved modes looked completely different, and some text (the guide-strip heading, the Search button label) rendered invisibly on dark panels. - Wrap the legacy stylesheet in @layer wolfbbs-legacy and add an unlayered brand layer, so brand colors and type win regardless of specificity - Brand layer uses only BRAND_SPEC v1.0 colors: ink/cream foundation, chrome buttons, copper rules, and green/yellow/red/magenta accents for meaning - PC6300 for headings, chrome and labels only; system sans for body; Menlo for code. The web font is embedded and served from /assets/fonts/ (CC BY-SA 4.0, attribution included) - Drop !important from legacy paint declarations so the layer order holds Fixes #2 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
External email requires a verified account, but nothing ever verified the bootstrap sysop, so the operator configuring SMTP was blocked by their own prerequisite. "Verified" also had no path besides a sysop checkbox. - Mark the bootstrap sysop verified on creation and on every start - Confirming a recovery email marks the account verified, since it proves control of an outside mailbox Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Two sources of truth for the name (installer .env vs. /admin/config) left the board with a split identity, and nothing prompted a fork to stop calling itself WolfBBS. - identity.env holds the public name and repo; the installer uses it for banners, FIRST_STEPS, and the default WOLFBBS_BBS_NAME - A bare bootstrap on a fork that still says WolfBBS asks for a name and saves it to identity.env - Web, SSH, IRC, and login banners fall back to WOLFBBS_BBS_NAME, now passed to the bbs, web, and irc containers; neutral wording replaces hard-coded WolfBBS in the web UI - Internals (WOLFBBS_* settings, wolfbbs Docker project and volume, binaries, Go module) keep the WolfBBS name as provenance - README leads with ResoNET BBS and credits WolfBBS; LICENSE keeps the original notice and adds a line for fork changes - Fix prompt_default printing its prompt into the captured answer, which corrupted install dir, ports, and repo edits in the guided install menu - Update installer regressions for the WIPE guard and assert --yes alone no longer deletes volumes Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The web UI had no favicon. Crop the Resonant Mirror emblem (the rings and light line, without the wordmark, which is unreadable at tab size) and serve: - /favicon.ico with 16, 32 and 48 px images - /assets/icons/icon-32, -192, -512 PNGs and a 180 px apple-touch-icon - icon links injected into every page head unless a page sets its own Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Replace the no-op Theme menu button (the brand layer overrides the old themes) with a Phosphor switcher using the portfolio's five palettes (P1 green, P3 amber, CGA cyan, Hermes bronze, Resonant violet); it colors CRT surfaces only, so browsers can't drift apart again - Add a CRT banner to /start and /connect: the board name on a phosphor screen with scanlines, plus PALETTE and EMBLEM/BANNER toggles - Add the portfolio's thin blue-violet-pink-amber strips along the page top, page header, banner and nav row - Stop the recent-pages rail filling with copies of one page: key entries by path without one-shot ?notice=/?error= params - Expose the board name to scripts via <meta name="application-name"> Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The table tools (filter, CSV/JSON export, columns), sticky/compact toggles, row inspector, "On this page" counters and the diagnostic/bug/feedback buttons are useful self-debugging aids but showed on every page for everyone. - Hide them by default; moderators and sysops get a "Sysop tools" checkbox at the top left that shows them (remembered per browser) - Pass the viewer's role and the live /admin/config site name to page scripts via <meta> tags (the CRT banner now uses the live name too) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
"Enable TOTP" switched 2FA on in one click without ever showing the secret, so nobody could produce a code and the next login failed. Codes are app-based and never emailed, which made the lockout look like missing mail. - Setup is now two steps: show a QR code (rsc.io/qr) and the key, and only turn 2FA on after a working code is entered; pending setups expire after 15 minutes and can be cancelled - Sysops get a "Reset 2FA" button per account in /admin/users (audited) - bootstrap.sh --reset-2fa <handle> clears 2FA through the local Docker socket, for when the sysop is the one locked out - Document all three in TROUBLESHOOTING.md and INSTALL.md Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The runtime reads doors/ and menus/ relative to /app, but neither Dockerfile copied them, so every Docker install started with zero doors (the launch check "Doors available" failed) and no menu file. - COPY doors and menus into /app in Dockerfile and Dockerfile.bundle - Include both in release bundles built by package-dist.sh Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Nothing backed up the database (users, boards, messages, and every setting saved in /admin/config and /admin/gateways) or .env. - --backup writes <prefix>/backups/<timestamp>/ (mode 700): pg_dump custom format, a .env copy, and a MANIFEST with commit and checksum; keeps the newest WOLFBBS_BACKUP_KEEP (default 14); removes incomplete dumps - --restore <dir> requires typed WIPE, takes a safety backup first (aborts if that fails), stops the app containers, pg_restore --clean, starts them - Document both in OPERATIONS.md and INSTALL.md Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Line input saved/restored the cursor with the SCO sequences CSI s / CSI u,
which macOS Terminal.app ignores, so every keystroke re-printed the whole
line ("Handle: MMoMooMoos..."). Use DEC ESC 7 / ESC 8, which every
VT100-compatible terminal supports.
- The Door Cockpit web page now says plainly that doors are played in the
terminal over SSH (press D), since the page is a catalog and scoreboard.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Show localhost URLs when ports are bound to 127.0.0.1 (the default), plus the public hostname saved in /admin/config; the LAN IP URLs didn't work - Read the live site name/hostname from the database, not just .env - Add a "Where things live" block: app source, compose file, .env, admin settings, database volume, backups, install folder; drop the "Managed app dir" line unless that folder exists (it's only used by curl | bash installs) - Replace the menu *.bak check, which could never pass on Docker installs (the editor writes inside the container), with "backup in the last 7 days" - FIRST_STEPS.txt: resolve the host before building URLs and honor the loopback bind, so all its links agree Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
After a line ended on a bare CR (what macOS Terminal.app sends for Enter), readLine peeked for a trailing LF, which blocks until the next keystroke. So the Password prompt didn't appear after Enter; pressing Enter again then gave an empty password, "Missing input", and the next key went back to Handle. - Only look for a trailing LF/NUL if it's already buffered; otherwise remember the bare CR and swallow a late LF/NUL at the start of the next read (readLine and readKey) - An empty password asks for the password again (up to 3 times) instead of returning to the Handle prompt - Tests for bare CR, late LF, and two empty Enters Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
/terminal serves an xterm.js page, and /terminal/ws bridges its WebSocket into the BBS SSH listener from inside the web container, so browser callers get the full ANSI board, login screen and doors with no SSH client. The backquote key drops the same terminal down over any site page. The bridge adds no auth: callers still sign in at the BBS login screen, and the socket only upgrades for same-host origins. With a shared WOLFBBS_TERMINAL_BRIDGE_SECRET the BBS records the caller's real IP instead of the web container's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The SSH server never set a host key, so gliderlabs generated a new one on every start and clients warned "REMOTE HOST IDENTIFICATION HAS CHANGED" after each rebuild. - Load the host key from WOLFBBS_SSH_HOST_KEY (default .wolfbbs/ssh/ssh_host_ed25519_key), creating an ed25519 key (mode 600) on first start; a corrupt key is reported, never overwritten - Keep it on a new "sshkeys" Docker volume so rebuilds don't replace it - --backup saves a copy of the host key - Document it in OPERATIONS.md Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…cally - /app upgrade: when the opt-in Docker socket and host mounts aren't present (the default since the socket became opt-in), say so and point to `bash bootstrap.sh --rapid-upgrade` instead of running a command that can only fail with "chdir /wolfbbs-host: no such file or directory" - Doors: reaching a door's per-session time limit (max_run_seconds) now shows "Time's up for this door session" and is recorded as door_timeout / a "timeout" door event, not door_failure "context deadline exceeded" Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The welcome panel hardcoded "WolfBBS Welcome", "wolfbbs (c) 2026" and a wolf. It now uses the configured site name (site.name / WOLFBBS_BBS_NAME) and the current year, and draws the ring-and-beam emblem from the web brand in ANSI instead of the wolf. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
--rapid-upgrade rebuilt whatever the local checkout held, so "merge on GitHub, then rapid-upgrade" silently shipped old code. It now fast-forwards the compose checkout from origin first when that is safe (the checkout's own root, on a branch, no uncommitted tracked changes, no local-only commits), and otherwise says why it is building as-is. WOLFBBS_RAPID_UPGRADE_NO_PULL=1 opts out. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Pressing (F)orest used to resolve a whole fight with one formula and print the result. It now opens a forest menu where you look for a monster, trade blows round by round with (A)ttack/(S)tats/(R)un, visit the healer's hut, and head back to town. Heroes get 15 forest fights a day; dying costs the gold you carry and a tenth of your XP and keeps you out until tomorrow. The door's session limit goes from 3 to 30 minutes so a full day of fights isn't cut off. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The AI door had no access check, so switching it on let every caller spend the sysop's model. Sysops now always have access; other users need to be listed in /admin/gateways (or SSH admin AIUSERS) and get a daily prompt cap (default 20, 0 = no limit). For local llama.cpp models: compose now passes the WOLFBBS_GATEWAY_AI_* env vars (including ALLOW_PRIVATE) into the bbs and web containers, a Skip thinking setting sends enable_thinking=false so reasoning models don't spend the whole token budget before answering, and an out-of-tokens reply says so instead of "ai response was empty". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The migration runner splits on every ';', so the semicolon in the 0005 comment left 'a sysop-chosen limit is left alone.' as its own statement and Postgres rejected it, stopping web, bbs and irc from starting. Adds a test that fails on any semicolon inside a migration comment. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Running the sshserver tests writes internal/sshserver/.wolfbbs/ssh/, and that throwaway key was committed by mistake. It is not the live board's key. Untrack it and ignore .wolfbbs/ssh/ everywhere. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Verified now means: confirmed recovery email, or 2FA active with recovery codes explicitly acknowledged. Confirming 2FA alone no longer implies anything; fresh code sets start unacknowledged; disabling 2FA or regenerating codes recomputes Verified unless a confirmed email holds it. Admin hand-verify and bootstrap grants are never revoked by flows that did not grant them. Co-Authored-By: Ara Voss <ara.voss.resonant.mirror@gmail.com>
Author
|
Opened against the wrong repo by mistake — this belongs on the fork. Closing to keep your queue clean. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Verified now means one of two honest things: a confirmed recovery email, or 2FA active with recovery codes explicitly acknowledged.
What changes:
Tests: 5 new (all watched fail first), full web + auth suites green. Local Codex review findings (2x P2) addressed in-branch.
Follow-ups intentionally out of scope: SSH-side parity, sysop lockout-hatch email on repeated failures, CSV export sort-glyph leak.