ANetBBS Changelog

Versions are internal build numbers. Public releases are tagged
separately. Current release: v1.0b2.58 (July 2026). Full release: August 1 2026.

v1.0a2.209 — Menu admin: add imsg / imsg_send / rss to action-type dropdown (July 2026)

v1.0a2.207 — Terminal MRC fixes; QWK blank-body diagnostic (July 2026)

  • Terminal /afk [msg] now sends AFK (not STATUS AFK), so the away message is visible to other chatters
  • Terminal /back now sends BACK instead of STATUS AFK
  • Fixed rate-limit error when sending first message after returning from AFK
  • Tab-complete now tracks users who join after you (USERIN/USEROUT/USERLIST/USERNICK parsed); from_user field used for nick tracking on chat messages
  • /chatters now sends CHATTERS (all rooms); /who//whoon send WHOON (current room)
  • QWK inbound: warning log when body is blank (first 256 raw bytes logged for diagnosis)
  • Admin: autocomplete="new-password" on QWK password field

v1.0a2.206 — Fix dosemu2 conf written to /tmp (July 1 2026)

dosemu2 temp files (conf and COM1 PTS path) were hardcoded to /tmp/. On
servers with restricted /tmp/ permissions the door failed immediately with
"Permission denied" before dosemu2 even launched. Both paths now use
temp_root() (<DATA_DIR>/temp/) which the service user always owns.

v1.0a2.205 — Fix menu hotkey duplication on update (July 1 2026)

seed_default_menus() ran on every startup and backfilled any default hotkey
not present in the sysop's menu. When a sysop rebound a hotkey (e.g. changed
MA for Message Boards), the original M was seen as "missing" and a
second Message Boards entry was added — causing duplicates on every update.

Fix: backfill now checks by (action_type, action_args) instead of hotkey.
If a menu already has a boards action (regardless of what key it's bound to),
no new boards item is added. Truly new features added in new releases still
backfill automatically, as long as their hotkey doesn't conflict.

v1.0a2.204 — Remove ANetCRAFT Enhanced and RDQ3 from release (July 1 2026)

  • Removed ANetCRAFT Enhanced web game: WEB_GAMES entry deleted from games/web_games.py,
    templates/games/web/anetcraft_enhanced.html deleted.
  • Removed Red Dragon Quest 3 door (doors/mystic/rdq3/) from the release package.

v1.0a2.203 — Beta release: package cleanup, REGISTRY_URL fix, docs update (July 1 2026)

  • REGISTRY_URL default changed from hardcoded hub URL to empty string. Sysops opt in to
    federation by setting REGISTRY_URL in Admin → Settings or .env. Preflight check now
    reports "not configured" instead of silently contacting an external host.
  • mrc/bridge/config.example.json: bridge_bbs changed to generic placeholder.
  • CHANGELOG v1.0a2.200 entry: removed internal tooling note.
  • README: status updated from alpha 2 to beta; removed broken doc link.

v1.0a2.202 — Auto-ban; IP whitelist; GeoIP country blocking; wiki edit gate (June 25 2026)

Security hardening and anti-spam protections.

  • Auto-ban: When the login rate limiter trips (10 attempts in 5 min), the source IP is
    permanently written to the IpBan table automatically — no sysop action needed. Visible and
    removable from Admin → IP Bans like any manual ban. Auto-bans have no expiry by default.
  • IP whitelist (Admin → IP Whitelist): New table ip_whitelist. Entries bypass all
    ban checks AND GeoIP country blocks. Use for sysop home IPs, trusted peers, and VPN exit
    nodes. Supports single IPs and CIDR ranges.
  • Country blocking: Set BLOCKED_COUNTRIES=CN,RU,KP (comma-separated ISO codes) in
    Admin → Settings. Blocks login and registration from listed countries. Uses
    ip-api.com — free, no registration, no download, no API key. Results
    cached in-memory for 1 hour so repeated login attempts don't add latency. Fails open
    (lookup error = allow) so a network hiccup never locks out users. Whitelisted IPs are exempt.
  • fail2ban configs (deploy/fail2ban/): Filter (filter.d/anetbbs-web.conf) matches
    nginx 429 responses on /auth/login. Jail (jail.d/anetbbs-web.conf) bans after 3 hits
    in 10 min for 24 h, covering ports 80, 443, 2233, 2234. Belt-and-suspenders on top of the
    in-process auto-ban above.
  • Wiki edit gate: New users must have at least 5 posts and a 3-day-old account before
    editing any wiki page. Configurable via WIKI_MIN_POSTS and WIKI_MIN_DAYS in Admin →
    Settings (set to 0 to disable). Admins are always exempt. Message tells the user exactly
    what requirement they don't yet meet.
  • New settings in Admin → Settings: BLOCKED_COUNTRIES, WIKI_MIN_POSTS, WIKI_MIN_DAYS.

v1.0a2.201 — Theme edit/delete; MSP toggle in Admin Settings (June 25 2026)

Theme management is now fully self-service from the admin UI.

  • Admin → Themes: Delete button added for each theme. The default theme's delete button is
    disabled (can't remove the fallback). A browser confirm dialog guards against accidents.
    Any users who had the deleted theme selected are automatically migrated to the system default.
  • Theme Builder: existing-themes table now has Edit and Delete action buttons alongside each
    row — no need to navigate away to Admin → Themes just to fix a name or remove a test theme.
  • Admin → Settings: MSP_ENABLED and MSP_PORT are now listed under Editable Settings.
    Sysops can toggle MSP (inter-BBS instant messaging, RFC 1312) on or off and change the port
    without editing .env manually. Flagged as requires-restart so the UI reminds you.

v1.0a2.200 — File areas manage page; echomail admin polish (June 25 2026)

  • File areas: new manage.html template for per-area file management.
  • Echomail admin network_form.html: UI improvements.
  • ANetCRAFT web game: anetcraft_enhanced.html template added.
  • QWK outbound diagnostics removed (verbose body hex dump + /tmp REP copy introduced in
    v1.0a2.198 no longer needed after confirmed fix).

v1.0a2.199 — QWK outbound: fix \r in body + MSGID space truncation (June 2026)

Two bugs in _build_rep_packet confirmed by hex-dumping the REP file:

  1. \r bytes left in body — body encoding converted \n\xe3 but left \r from
    Windows \r\n line endings, producing \r\xe3 instead of bare \xe3 throughout.
    Fix: replace \r\n first, then lone \r, then \n.

  2. MSGID space → Synchronet dupe truncation — auto-generated MSGID was
    ANETBBS_<hash> <timestamp>. Synchronet's qwk_import_msg calls truncstr(p, " ")
    on the MSGID, storing only ANETBBS_<hash>. That truncated stub is identical on every
    re-upload of the same message → dupe detection silently drops it.
    Fix: use underscore separator → ANETBBS_<hash>_<timestamp>.

Outbound messages to Dove-Net/vert.synchro.net confirmed working after this fix.

v1.0a2.198 — QWK diagnostics: REP saved to /tmp, body hex dump (June 2026)

Temporary diagnostics to pinpoint outbound QWK failures:
save REP to /tmp/anetbbs_last.rep; log first 64 bytes of body hex. Removed in v1.0a2.200.

v1.0a2.196–197 — QWK outbound: uppercase MSG filename, conf_num, space padding (June 2026)

  • Inner ZIP entry renamed VERT.MSG (uppercase) — Synchronet's un_rep.cpp filters on
    SAFEST_FILENAME_CHARS; lowercase extension caused silent extraction failure.
  • Body block padding changed from null bytes to spaces (0x20) per QWK spec.
  • Conference number extraction handles both plain numeric tags and legacy QWK_N prefix.

v1.0a2.189–195 — QWK outbound investigation series (June 2026)

Iterative fixes tracing why outbound messages weren't appearing on Dove-Net:
REP packet structure, FTP upload auth, conference mapping, area-tag normalisation,
hub_id vs packet_id distinction in filenames. See v1.0a2.186–188 for earlier steps.

v1.0a2.188 — QWK network form: hub_id field added; upload URL uses hub_id (June 2026)

Hub System ID field was missing from the network config form — the
qwk_hub_id field existed in the form class and was stored in the database,
but was never rendered in network_form.html. Sysops had no way to set it,
so it was always blank. The QWK client fell back to packet_id for all
filename generation, which produced correct filenames only if the sysop
happened to put the hub's ID in the packet ID field.

Added the Hub System ID field to the form alongside explanatory text
clarifying the two-ID model:
- Hub System ID (VERT) — used in ALL filenames: VERT.qwk download,
VERT.rep upload, VERT.MSG inside the zip. The hub's un_rep looks for
{hub_sys_id}.MSG; if wrong the entire REP is silently rejected.
- Packet ID (ANETBBS) — your node's registered ID. Used for FTP login
identity and auto-generated @MSGID: values. Does not appear in filenames.

Also exposed the download URL and upload URL override fields in the form
(both were hidden — also never rendered in the template).

Default upload URL changed from ftp://dove.synchro.net/{packet}.rep to
ftp://dove.synchro.net/{hub_id}.rep — the outer REP file should be named
with the hub's ID (same convention as the download), not the node's ID. The
node is identified by the FTP login credentials, not the filename.

After deploying: go to /admin/echomail → DOVE-Net → set:
- QWK Hub System ID = VERT
- QWK Packet ID = your registered node ID (e.g. ANETBBS)

v1.0a2.187 — QWK area tags: plain numeric format per Dove-Net docs (June 2026)

QWK conference areas are now tagged with the plain conference number (e.g.
2010) instead of the QWK_2010 prefix that ANetBBS was incorrectly
prepending. The QWK spec and Dove-Net documentation identify conferences by
number only; the prefix was an internal ANetBBS convention that wasn't needed.

Auto-migration: on first inbound message for each conference, the importer
now detects any existing QWK_N area and renames it to the plain numeric tag
automatically — no manual database edits required.

Outbound conf_num extraction now handles both plain numeric tags (2010)
and legacy QWK_N tags (QWK_2010) so existing installations keep working
until migration completes.

Quick-add (/admin/echomail → QWK network → quick-add) also migrates old
QWK_N entries to plain numeric tags when encountered.

Admin form hint updated to clarify: FTN areas use FIDO_GENERAL-style
tags; QWK areas use the plain conference number.