misc
This commit is contained in:
1 parent
490444032c
commit
efecc500c4
15 files changed
+349
-47
No files matched your search
@@ -61,13 +61,20 @@ Environment; see *Contact form* below.
|
||||
- **Contact form.** The form posts `first_name`, `last_name`, `email`, `message`, `lang` and a
|
||||
honeypot field `website` to `POST /contact`. That one path is handled by `server/contact.mjs`
|
||||
(Node, nodemailer), which sends the message by SMTP to `CONTACT_TO` with the sender as
|
||||
Reply-To. With scripting the form sends in place and shows the result under the button;
|
||||
without, the handler redirects to `/contact/sent` or `/contact/error` (under `/de` for German).
|
||||
Both pages are `noindex` and left out of the sitemap. The handler caps size and field lengths,
|
||||
refuses cross-site posts, and allows 5 messages per address per 10 minutes and 60 per hour
|
||||
overall.
|
||||
Reply-To. The form sends in place and shows the result in a toast; a post that asks for HTML
|
||||
is redirected to `/contact/sent` or `/contact/error` (under `/de` for German). Both pages are
|
||||
`noindex` and left out of the sitemap. The handler caps size and field lengths, refuses
|
||||
cross-site posts, and allows 5 messages per address per 10 minutes and 60 per hour overall.
|
||||
|
||||
In the container, nginx proxies `/contact` to the handler on `127.0.0.1:3000`; both are started
|
||||
Against spam, every message carries the answer to a proof-of-work challenge (ALTCHA,
|
||||
`altcha-lib`). The form fetches a signed challenge from `GET /contact/challenge` when the
|
||||
visitor first focuses it and solves it in the background (about half a second on a laptop, one
|
||||
to two on a phone). The handler refuses a post without a valid, unexpired, unused solution, or
|
||||
one sent less than 3 seconds after the challenge was issued. Nothing is stored in the browser
|
||||
and no third party is involved, so there is nothing to consent to. The form therefore needs
|
||||
JavaScript; without it a `<noscript>` line points to the email address.
|
||||
|
||||
In the container, nginx proxies `/contact` and `/contact/challenge` to the handler on `127.0.0.1:3000`; both are started
|
||||
by `docker/entrypoint.sh`, which restarts the handler if it crashes. If the handler is down,
|
||||
visitors are sent to the error page. Without SMTP settings the handler does not start and the
|
||||
rest of the site is served as usual.
|
||||
@@ -81,10 +88,11 @@ Environment; see *Contact form* below.
|
||||
| `CONTACT_TO` | `office@ciphercell.de` | Where messages go. |
|
||||
| `SMTP_SECURE` | by port | Force TLS from the start (`true`) or not (`false`). |
|
||||
| `SMTP_REQUIRE_TLS` | `true` | `false` only for a local mail catcher. |
|
||||
| `ALTCHA_HMAC_SECRET`, `ALTCHA_HMAC_KEY_SECRET` | random per start | Signing secrets for the challenge (`openssl rand -hex 32`). Set them so a restart does not void challenges already handed out. |
|
||||
|
||||
In Dokploy, set these under the application's Environment. Locally, put them in `.env` (see
|
||||
`.env.example`), run `npm run contact` next to `npm run dev`; the dev server proxies `/contact`
|
||||
to it.
|
||||
`.env.example`), run `npm run contact` next to `npm run dev`; the dev server proxies `/contact` and
|
||||
`/contact/challenge` to it.
|
||||
- **Alpha sign-up.** While `verifierComingSoon` in `src/data/flags.ts` is true, `/cipherverifier`
|
||||
shows a coming-soon page whose form posts `email`, `consent=yes`, `lang`,
|
||||
`list=cipherverifier-alpha` and the honeypot `website` to `POST /notify`. The handler is
|
||||
|
||||
Reference in new issue
Block a user