This commit is contained in:
parent
aa2327ff1d
commit
2fa6e70af1
10 changed files with 619 additions and 20 deletions
|
|
@ -315,6 +315,72 @@ unattended; the keyring lives in the 0700 StateDirectory. With a key configured,
|
|||
a signing failure is a 500 — an unsigned invoice is never served by accident.
|
||||
Without one (dev), invoices carry a visible UNSIGNED marker.
|
||||
|
||||
## Order email (confirmation + invoice)
|
||||
|
||||
A paid order gets one confirmation email with the clearsigned invoice
|
||||
attached — plain text plus a markdown attachment, no HTML part, no remote
|
||||
resources, nothing the privacy notice would have to explain. The mailer
|
||||
watches the ledger, so every path to paid (reconciler, arrival poll, a manual
|
||||
`--mark-paid` even on a later restart) results in exactly one email: the
|
||||
`notified` event, appended only after the mail command accepts the message,
|
||||
is what stops a resend.
|
||||
|
||||
Delivery shells out to a **sendmail-compatible command** rather than speaking
|
||||
SMTP itself, for the same reason invoices shell out to gpg: TLS, AUTH and
|
||||
deliverability are exactly what msmtp already does well, and the volume is a
|
||||
handful of messages per week. Deliverability stays the mailbox provider's
|
||||
problem (SPF/DKIM are theirs), and no third party beyond the provider that
|
||||
already handles `info@catcrafts.net` ever sees order data — which is what the
|
||||
privacy page implies.
|
||||
|
||||
```sh
|
||||
apt install msmtp
|
||||
|
||||
cat > /etc/msmtprc <<'CONF'
|
||||
defaults
|
||||
auth on
|
||||
tls on
|
||||
tls_starttls on
|
||||
account catcrafts
|
||||
host smtp.your-mail-provider.example
|
||||
port 587
|
||||
from info@catcrafts.net
|
||||
user info@catcrafts.net
|
||||
passwordeval cat /etc/catcrafts/smtp-password
|
||||
account default : catcrafts
|
||||
CONF
|
||||
chmod 0644 /etc/msmtprc
|
||||
|
||||
# msmtp runs as the service user, so the password file must be readable by
|
||||
# it — unlike payments.env, which only root (systemd) reads.
|
||||
install -o catcrafts -g catcrafts -m 0600 /dev/null /etc/catcrafts/smtp-password
|
||||
# ...then put the SMTP password in that file.
|
||||
```
|
||||
|
||||
Then in `/etc/catcrafts/payments.env`:
|
||||
|
||||
```
|
||||
MAIL_COMMAND=msmtp -t
|
||||
MAIL_FROM=Catcrafts <info@catcrafts.net>
|
||||
```
|
||||
|
||||
and `systemctl restart catcrafts-server` — the journal should say
|
||||
`mail: order confirmations via 'msmtp -t'`. Unset, no email is sent and the
|
||||
order page plus the invoice download remain the buyer's receipt: degraded,
|
||||
not down, like every optional integration here.
|
||||
|
||||
Worth knowing:
|
||||
|
||||
* A failed handoff retries with exponential backoff (1 min doubling to a cap
|
||||
of ~an hour), forever — a broken relay delays the email, it never eats it.
|
||||
Watch `journalctl -u catcrafts-server | grep 'mail:'` after changing config.
|
||||
* With a signing key configured, a gpg failure means the email WAITS — an
|
||||
unsigned invoice never leaves by accident, same rule as the download.
|
||||
* Send a real test: `--rail=fake` locally with `MAIL_COMMAND` pointing at
|
||||
msmtp and your own address in the order form, or just run `tools/e2e.sh`,
|
||||
which captures the messages with a fake sendmail and verifies the attached
|
||||
signature.
|
||||
|
||||
## Reading the orders ledger
|
||||
|
||||
```sh
|
||||
|
|
@ -435,10 +501,11 @@ split working as designed.
|
|||
tools/fetch-posts.sh # pull posts from the allowed communities
|
||||
tools/fetch-media.sh [dir] # mirror their media locally (run after the above)
|
||||
tools/fetch-rates.sh # ECB reference rates for the indicative prices
|
||||
tools/e2e.sh # 143 HTTP checks against a real server; the CI gate
|
||||
tools/e2e.sh # ~200 HTTP checks against a real server (135 while
|
||||
# coming-soon; the rest re-arm at launch); the CI gate
|
||||
crafter-build --local -r # the wasm app alone, no backend, on :8080
|
||||
|
||||
<server>/catcrafts-server --selftest # ~140 in-process assertions
|
||||
<server>/catcrafts-server --selftest # ~260 in-process assertions
|
||||
<server>/catcrafts-server --routes # status + title for every route
|
||||
<server>/catcrafts-server --render /projects # dump one page's HTML
|
||||
<server>/catcrafts-server --orders FILE # the orders ledger + manual transitions
|
||||
|
|
|
|||
|
|
@ -79,6 +79,9 @@ ReadOnlyPaths=/srv/catcrafts-app /srv/catcrafts.net
|
|||
# MOLLIE_API_KEY=live_... (or test_... while verifying) — the rail
|
||||
# SENDCLOUD_PUBLIC_KEY / SENDCLOUD_SECRET_KEY / SENDCLOUD_METHOD — optional,
|
||||
# live shipping rates; zone table without them
|
||||
# INVOICE_GPG_KEY=... invoice signing (see deploy/README.md)
|
||||
# MAIL_COMMAND=msmtp -t order confirmation email (see deploy/README.md,
|
||||
# MAIL_FROM=... "Order email"); unset = no email is sent
|
||||
# BUNQ_API_KEY=... legacy: only used when no Mollie key is set
|
||||
# The '-' prefix makes the file optional: without it the server starts with
|
||||
# payments off and the shop renders but refuses checkout — degraded, not down.
|
||||
|
|
|
|||
Loading…
Reference in a new issue