diff --git a/README.md b/README.md index 954adb1..509f18b 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,10 @@ Ops: ./agentbbs notify-creds --user alice --mail --send ``` +Member git accounts, mailbox welcome emails, `notify-creds`, and the two SMTP +paths (transactional `:587` vs. the gateway relay `:25`) are documented in +[`docs/credentials.md`](docs/credentials.md). + ## Deploy ### Hosting requirements diff --git a/docs/credentials.md b/docs/credentials.md new file mode 100644 index 0000000..03601f0 --- /dev/null +++ b/docs/credentials.md @@ -0,0 +1,94 @@ +# Member credentials — git accounts, mailboxes & the `notify-creds` backfill + +Every **verified** AgentBBS member gets, for free: + +- a **git account** on `git.profullstack.com` (the self-hosted Forgejo backing + AgentGit) — BBS membership *is* the git account, and +- a **mailbox** at `@mail.profullstack.com` (self-hosted Mailu — see + [`mail.md`](mail.md)). + +This doc covers how those credentials are delivered by email, and the +`agentbbs notify-creds` ops command that (re)sends them. + +## Git accounts (automatic) + +When a member confirms their email, `provisionGit` (`cmd/agentbbs/main.go`): + +1. **Creates** their Forgejo account (`forgejo.EnsureUser`) with a generated + one-time password (`must_change_password`), if it doesn't exist. +2. **Registers** the SSH key they signed in with (`forgejo.EnsureKey`) so they + push with the same key — no git password. +3. **Emails** them the web sign-in link, username, and the one-time password + (`gitWelcomeEmailBody`) via the transactional SMTP relay. + +It's idempotent and best-effort: failures are logged, never blocking BBS +verification, and it's a no-op when Forgejo is unconfigured. It runs on email +verification (`join@` and the web `/verify` link) and again, asynchronously, on +each BBS login so an existing member's key is kept in sync. + +## `notify-creds` — backfill / re-send (ops) + +The git- and mailbox-credential emails were added after some accounts already +existed, so `notify-creds` lets the operator send them to members who never +received them. Run it on the host where the DB and env live. + +```bash +agentbbs notify-creds # PREVIEW for all verified members (sends nothing) +agentbbs notify-creds --send # really send git + mailbox to everyone verified +agentbbs notify-creds --git --send # git creds only +agentbbs notify-creds --mail --send # mailbox creds only +agentbbs notify-creds --user alice,bob --send +``` + +| Flag | Effect | +|---|---| +| *(none)* | **Preview only** — scans and prints intended actions; resets no passwords, sends no mail. | +| `--send` | Actually reset passwords, ensure aliases, and send email. | +| `--git` | Include git creds (default: both when neither `--git`/`--mail` is given). | +| `--mail` | Include mailbox creds. | +| `--user a,b` | Restrict to a comma-separated allow-list (default: all verified). | +| `--limit N` | Max accounts to scan (default 100000). | + +What `--send` does per verified member (banned / unverified / no-email are +skipped): + +- **git** — `forgejo.EnsureUserReset`: creates the account if missing, otherwise + **resets it to a fresh one-time password** (the original is not recoverable), + then emails the login link + username + password. The reset clobbers any + password a member set themselves, which is why it only runs under `--send`. +- **mail** — `forwardemail.CreateAlias` to ensure the `@` alias, + then emails the address + webmail link. + +Safety rails: it **refuses `--send` when SMTP is unconfigured**, and +**warns-and-skips** the git or mail channel when Forgejo / forwardemail are +unconfigured. It prints a per-channel `sent / failed` summary and exits non-zero +on any failure. + +> The `--mail` path uses the **forwardemail.net** alias API +> (`AGENTBBS_FORWARDEMAIL_*`), which is independent of the self-hosted Mailu +> mailbox stack in [`mail.md`](mail.md). Use whichever your deployment has wired. + +## Required env + +| Var | Default | For | +|---|---|---| +| `AGENTBBS_FORGEJO_URL` | unset | git — Forgejo base URL, e.g. `https://git.profullstack.com` | +| `AGENTBBS_FORGEJO_ADMIN_TOKEN` | unset | git — Forgejo admin token (create/reset users + keys) | +| `AGENTBBS_FORWARDEMAIL_API_KEY` | unset | mail — forwardemail.net API key | +| `AGENTBBS_FORWARDEMAIL_DOMAIN` | `AGENTBBS_MAIL_DOMAIN` | mail — alias domain (falls back to the mail domain, default `mail.profullstack.com`) | +| `AGENTBBS_WEBMAIL_URL` | unset | mail — webmail link put in the email (optional) | +| `AGENTBBS_SMTP_HOST` / `_FROM` | unset | **sending** all of the above emails (required to actually send) | +| `AGENTBBS_SMTP_PORT` / `_USER` / `_PASS` | `587` / unset / unset | SMTP submission (STARTTLS) | + +## Two SMTP paths (and why one is `:25`) + +AgentBBS has **two different SMTP configs** — don't confuse them: + +| Config | Default | Role | +|---|---|---| +| `AGENTBBS_SMTP_*` (`internal/mail`) | port **`587`** (STARTTLS) | **Transactional sender** — `join@` confirmation codes and all `notify-creds` emails. This is an authenticated *submission* port. **Implicit-TLS `465` is not supported** by this code path (it negotiates STARTTLS); use 587 or another STARTTLS port. | +| `AGENTBBS_MAIL_SMTP_ADDR` (`internal/mailbox`) | **`127.0.0.1:25`** | **Gateway relay** — how the in-BBS `Mail` client injects members' outbound mail into the **on-box Mailu/Postfix MTA**. `:25` is correct here: it's a trusted *loopback* hand-off to the local MTA, not a remote authenticated client. 465/587 are submission ports for *remote* clients and don't apply. | + +So a `127.0.0.1:25` in the mail config is intentional, not a bug. (And there is +no SMTP port `467` — the implicit-TLS submission port is `465`.) See +[`mail.md`](mail.md) for the full Mailu stack. diff --git a/docs/mail.md b/docs/mail.md index 60cd0b4..b4bac4b 100644 --- a/docs/mail.md +++ b/docs/mail.md @@ -103,6 +103,13 @@ Without `AGENTBBS_MAIL_API_TOKEN` auto-provisioning is skipped (the address is still shown); without `AGENTBBS_MAIL_MASTER_PASS` the gateway can't open mailboxes. +> **`AGENTBBS_MAIL_SMTP_ADDR` is `127.0.0.1:25` on purpose** — it's the gateway's +> *loopback* hand-off into the on-box Mailu/Postfix MTA, not a remote submission +> client, so `25` is correct (465/587 are for authenticated remote clients). +> This is a separate config from `AGENTBBS_SMTP_*` (the transactional sender for +> confirmation codes and `notify-creds`, which defaults to STARTTLS `:587`). See +> [`credentials.md`](credentials.md#two-smtp-paths-and-why-one-is-25). + ### Why the gateway talks to Dovecot directly (plaintext loopback) Mailu's **front** (nginx mail proxy) pre-authenticates every IMAP/SMTP login