agentbbs/internal
Anthony Ettinger 006235ce92
Feat/mail all members (#55)
* feat(mail): give every verified member a free @bbs.profullstack.com mailbox

Email was built but paid-only (Founding Lifetime gate) and never wired to a
running backend. Make it a free benefit of membership and split the address
domain from the mail-server host.

- internal/mailu: Mailu admin-API client; EnsureUser idempotently provisions a
  mailbox via the loopback admin REST API (token = mailu.env API_TOKEN).
- main.go: auto-provision <name>@<mailDomain> at join@ verification and on first
  Mail open; un-gate the Mail hub entry + mail@ (membership/email-verified, not
  Premium); address domain (AGENTBBS_MAIL_ADDR_DOMAIN, default the BBS host) is
  now distinct from the mail server host (AGENTBBS_MAIL_DOMAIN) and the webmail
  URL. Drop the forwardemail alias path (Mailu now owns delivery for everyone).
- mailbox: gate on membership (a registered handle) instead of Paid;
  ErrNotPaid -> ErrNotMember.
- join@ copy: list email under free membership; premium now pitches custom
  domains + Tor only.
- setup.sh / docs/mail.md / deploy/mailu: address-domain vs server-host split,
  Mailu API token, MX for the address domain, local-relay SMTP for verify codes.

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

* chore(mailu): pin Docker network subnet to match SUBNET; ignore runtime state

The base compose declares no network, so Docker assigns the default bridge an
arbitrary subnet that won't match mailu.env SUBNET — breaking Mailu's internal
service auth/relay. Add a docker-compose.override.yml.example that pins the
default network to 192.168.203.0/24, and gitignore the live override + Mailu
runtime state (mailu.env, certs/, data/).

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

* feat(mail): plaintext loopback IMAP so the gateway bypasses Mailu's front

Mailu's front (nginx mail proxy) pre-authenticates against Mailu's user DB before
proxying to Dovecot, which rejects the Dovecot master-user login <addr>*gateway.
The gateway must reach Dovecot directly. The imap container has no TLS cert (only
the front does), so the bypass is plaintext over loopback — the master password
never leaves the host.

- mailbox: IMAPConfig.Plaintext dials with DialInsecure (loopback only).
- main.go: mailClientFor sets Plaintext from AGENTBBS_MAIL_IMAP_PLAINTEXT.
- override.example: add the unbound resolver (admin needs DNSSEC), webmail image
  fix (2024.06 uses mailu/webmail), and publish Dovecot 143 on 127.0.0.1:14143.
- docs/mail.md: document the front-bypass, the dovecot.conf master passdb (Mailu
  includes that exact filename), and the 644 master-users perms (640 = temp_fail).

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

* deploy(mailu): wire gateway IMAP to the loopback Dovecot path in setup.sh

setup.sh §9e set AGENTBBS_MAIL_IMAP_ADDR to the front's :993, which the front's
auth proxy rejects for the master-user login (and would clobber the working
loopback wiring on every self-update). Point it at 127.0.0.1:14143 +
AGENTBBS_MAIL_IMAP_PLAINTEXT=1 instead, matching the override + docs.

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

* feat(mail): give free members a webmail password at join@

The gateway opens mailboxes via the Dovecot master user (no member password),
but webmail (Roundcube) needs the member to have a password. join@ now sets a
fresh, readable webmail password via the Mailu API and shows it with the webmail
URL + login, so free members can use webmail at mail.profullstack.com.

- mailu: SetPassword (PATCH /user/<email> raw_password) + test.
- main.go: setWebmailPassword + readablePassword; join@ displays url/login/password.

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 03:38:31 -07:00
..
admin Fix/pod public html bind mount (#30) 2026-06-15 08:06:32 -07:00
ascii Video calls (PairUX→ASCII), agent@ chat, and finger routes 2026-06-11 11:43:38 +00:00
auth fix: add GameNames to IsReservedName checks (#42) 2026-06-22 05:23:50 -07:00
brand Use the Profullstack </> ASCII logo as the BBS banner 2026-06-14 16:46:59 +00:00
calls Video calls (PairUX→ASCII), agent@ chat, and finger routes 2026-06-11 11:43:38 +00:00
chat Video calls (PairUX→ASCII), agent@ chat, and finger routes 2026-06-11 11:43:38 +00:00
forgejo feat(agentgit): register members' SSH keys + enable git push over SSH 2026-06-23 08:39:37 +00:00
forwardemail Autonomous deploy + free-pod/Premium-email membership 2026-06-14 07:58:51 +00:00
games M3: AgentGames — agent-vs-agent games, ELO ladder, replays (#7) 2026-06-14 03:30:12 -07:00
hub Fix/pod public html bind mount (#30) 2026-06-15 08:06:32 -07:00
mail bbs.profullstack.com launch kit: provisioner, custom domains, email verify, ascii-live 2026-06-11 15:53:19 +00:00
mailbox Feat/mail all members (#55) 2026-06-23 03:38:31 -07:00
mailu Feat/mail all members (#55) 2026-06-23 03:38:31 -07:00
news fix: reject malformed NNTP OVER ranges instead of returning all articles (#48) 2026-06-22 05:22:58 -07:00
payments Rebrand paid tier to $99 Founding Lifetime Member 2026-06-14 12:46:23 +00:00
plugin fix(arcade): give ncurses games a TERM so they launch 2026-06-18 12:01:26 +00:00
pods feat(pods): SSH agent forwarding → git push from the pod with your key 2026-06-23 09:16:29 +00:00
qryptinvite Fix flaky TestTamperedTokenFails in qryptinvite 2026-06-14 17:05:30 +00:00
sandbox AgentBBS: M0 core hub, M1 arcade, pods with CoinPay membership 2026-06-11 11:08:17 +00:00
sites Free per-user homepages at <name>.<host> (wildcard subdomains) 2026-06-14 09:20:34 +00:00
source fix: block shared/reserved IP ranges in SSRF guard (#47) 2026-06-22 05:23:15 -07:00
store Fix unused and ineffectual variables (#32) 2026-06-16 03:21:39 -07:00
tor tor: premium tor-url / tor-irc / tor routes over Tor 2026-06-14 10:54:21 +00:00
ui Fix/pod public html bind mount (#30) 2026-06-15 08:06:32 -07:00