Skip to content

Releases: dc9-dev/formd

formd v0.3.0

Choose a tag to compare

@dc9-dev dc9-dev released this 19 Oct 14:07

formd

formd is a self-hosted form backend for static sites: one Go binary next to your site that accepts submissions, filters out bots without a captcha, stores them in SQLite and sends email through your SMTP server or Amazon SES.

Website with a live demo: https://formd.top

What's new: English and Polish

formd now speaks English by default and Polish on request.

  • Panel, emails to you and the CLI follow the new FORMD_LANG setting: en (default) or pl. New forms get default field labels and email texts in that language; existing forms keep their own.
  • Visitors get messages in the language of your page. formd.js reads the lang attribute nearest to the form (usually <html lang>), shows its messages in English or Polish, and passes the language to the server so that field errors match. A plain form post without JavaScript uses the browser's Accept-Language. No configuration is needed on a Polish or an English site.
  • Other languages still work through the data-formd-* attributes on the form.
  • Polish mode shows exactly the same texts as before: every English message has a Polish entry, and a test fails if one is missing.
  • The example form is now in English (examples/contact.html), with the Polish one in examples/contact.pl.html.

Upgrading from v0.2.0

The panel is now in English by default. To keep it in Polish, add this to /etc/formd/formd.env:

FORMD_LANG=pl

Then replace the binary and restart: sudo systemctl restart formd. There are no database changes. Existing forms keep their labels and email texts.

Visitor messages on Polish pages (<html lang="pl">) stay Polish. If your pages have no lang attribute, or an English one, visitors now get English messages; set lang="pl" on the page to keep Polish.

Install

# Linux x86-64 (for ARM use formd-linux-arm64)
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.3.0/formd-linux-amd64
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.3.0/SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS
sudo install -m 0755 formd-linux-amd64 /usr/local/bin/formd
formd version   # v0.3.0

Or from source: go install github.com/dc9-dev/formd/cmd/formd@v0.3.0 (Go 1.27.2+). Full guide: formd.top.

Files

File Platform
formd-linux-amd64 Linux x86-64, statically linked
formd-linux-arm64 Linux ARM64, statically linked
SHA256SUMS checksums

Built from commit f5a7f5c with Go 1.27.2 (CGO_ENABLED=0, -trimpath).

formd v0.2.0

Choose a tag to compare

@dc9-dev dc9-dev released this 19 Oct 13:13

formd

formd is a self-hosted form backend for static sites: one Go binary next to your site that accepts submissions, filters out bots without a captcha, stores them in SQLite and sends email through your SMTP server or Amazon SES.

Website with a live demo: https://formd.top

What's new

Content assessment with a Polish model on your own hardware

  • New JEV_PROVIDER=basal: formd sends content assessment to a self-hosted basal-serve instead of Jev on OpenRouter. It speaks the same System One API, so the questions, thresholds, holding and fail-open work the same.
  • Defaults to Remek/basal-omni-1.0-ultra at http://127.0.0.1:8000/v1/systemone. The lighter Bielik-based Remek/basal-2.0-4.5B also runs on a Mac or a CPU; set JEV_MODEL to the name you serve.
  • Form content stays on your infrastructure and requests cost nothing, so the panel hides the cost tile. The form settings show which model scores submissions and whether content leaves the server.
  • Security: basal-serve has no authentication, so plain http is still accepted only for a loopback address; a remote model needs https. OPENROUTER_API_KEY is never sent to a basal endpoint; an optional BASAL_API_KEY is sent to a gateway in front of it. An unknown JEV_PROVIDER stops startup with a clear error.
  • Step-by-step setup: README.

The integration is tested against the API format documented by basal, not against a GPU deployment. If something does not match, submissions go through without a score and the panel shows the error.

Website and docs in English and Polish

  • formd.top is now in English at / and in Polish at /pl/, chosen from the browser language on the first visit, with a switch that remembers the choice.
  • The README is in English; the Polish version moved to README.pl.md. Both have a comparison with hosted form services and an FAQ.
  • The English install guide sets English visitor messages through the data-formd-* attributes. formd's built-in messages and the admin panel are still Polish.

Install

# Linux x86-64 (for ARM use formd-linux-arm64)
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.2.0/formd-linux-amd64
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.2.0/SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS
sudo install -m 0755 formd-linux-amd64 /usr/local/bin/formd
formd version   # v0.2.0

Or from source: go install github.com/dc9-dev/formd/cmd/formd@v0.2.0 (Go 1.27.2+). Full guide: formd.top.

Upgrading from v0.1.0

Replace the binary and restart: sudo systemctl restart formd. There are no database changes and no required configuration changes; without JEV_PROVIDER, formd keeps using Jev on OpenRouter as before.

Files

File Platform
formd-linux-amd64 Linux x86-64, statically linked
formd-linux-arm64 Linux ARM64, statically linked
SHA256SUMS checksums

Built from commit ffb9d62 with Go 1.27.2 (CGO_ENABLED=0, -trimpath).

formd v0.1.0

Choose a tag to compare

@dc9-dev dc9-dev released this 15 Oct 16:36

formd

Pierwsze wydanie formd: samodzielnego backendu formularzy dla stron statycznych. Jedna binarka w Go, którą instalujesz na tym samym serwerze co stronę. Przyjmuje formularz, waliduje go, zapisuje do SQLite i wysyła powiadomienie oraz potwierdzenie przez Twój SMTP albo Amazon SES. Bez SaaS-ów i bez captchy od firm trzecich.

Strona projektu: https://formd.top

Co nowego

Ocena treści przez Jev (opcjonalna)

  • Każde zgłoszenie może dostać ocenę modelu Jev (TypeSafe, przez OpenRouter): kategorię, prawdopodobieństwo spamu, oszustwa lub phishingu, treści obraźliwej i pilność.
  • Powyżej progu ryzyka (domyślnie 70%) formularz:
    • wstrzymuje zgłoszenie do zatwierdzenia w panelu, razem z mailami (domyślnie),
    • oznacza maile prefiksem [SPAM?],
    • albo odrzuca je bez zapisu.
  • Jev jest pytany dopiero po wszystkich tanich filtrach. Ma dzienny budżet (JEV_DAILY_BUDGET_USD) i timeout 4 s. Gdy nie odpowie, zgłoszenie domyślnie przechodzi bez oceny.
  • Prywatność: funkcja jest wyłączona, dopóki nie ustawisz OPENROUTER_API_KEY i nie włączysz jej w formularzu. Adresy e-mail są zastępowane samą domeną.
  • Treść od użytkownika trafia tylko do opisu sytuacji, w osłoniętych blokach, oznaczona jako niezaufana. Klucz API nie pojawia się w logach.

Nowy panel administracyjny

  • Jasny, lekki wygląd z wyraźnym logo; font Geist wbudowany w binarkę (bez zasobów z zewnątrz).
  • Strona główna z podsumowaniem (zgłoszenia, wstrzymane, nieudane maile, dzisiejszy koszt Jev) i listą formularzy.
  • Zakładka Wstrzymane z przyciskiem „Zatwierdź i wyślij” oraz ocena Jev przy każdym zgłoszeniu.
  • Wyraźny fokus, link „Przejdź do treści”, ruch wyłączany przy prefers-reduced-motion.

Komunikaty formd.js w innych językach

  • Atrybuty data-formd-sending, -success, -error, -network-error nadpisują domyślne polskie komunikaty dla danego formularza.
  • data-formd-server-errors="off" ukrywa szczegółowe komunikaty walidacji z serwera.
  • Bez tych atrybutów działanie się nie zmienia.

HTTPS i reverse proxy

  • Pełne konfiguracje nginx dla dwóch wariantów, z certyfikatem, przekierowaniem 80→443 i HSTS:
    • formularz na tej samej domenie co strona,
    • osobna subdomena, gdy strona leży na GitHub Pages, Netlify albo S3.
  • Ten sam zestaw dla Caddy.
  • W README: dlaczego formularz musi trafiać na HTTPS, kroki z certbotem i komendy curl do sprawdzenia wdrożenia.

Bezpieczeństwo

  • Wymagane Go 1.27.2: usuwa 12 podatności biblioteki standardowej (m.in. w html/template) zgłoszonych przez govulncheck.
  • Zaktualizowane moduły golang.org/x (crypto, net, sys, term).
  • Naprawione logowanie do panelu w przeglądarkach wysyłających Origin: null. Takie żądanie przechodzi tylko wtedy, gdy przeglądarka potwierdzi Sec-Fetch-Site: same-origin.

Co jest w środku

  • API formularzy POST /f/{id}: urlencoded, multipart (bez plików) i JSON. Bez JS przekierowanie 303, z fetch odpowiedź JSON.
  • Ochrona przed masową wysyłką:
    • podpisany, jednorazowy token HMAC z proof-of-work zamiast captchy,
    • minimalny czas wypełnienia liczony na serwerze,
    • limity per IP, per formularz i globalne,
    • limit potwierdzeń na adres na dobę,
    • honeypot, filtr linków i fraz, odrzucanie duplikatów.
  • Sieć: nasłuch tylko na konkretnym IP (0.0.0.0 jest odrzucane), allowlista IP, X-Forwarded-For honorowany wyłącznie od zaufanego proxy.
  • Panel na osobnym porcie (przez tunel SSH):
    • argon2id, sesje po stronie serwera, CSRF,
    • SameSite=Strict, ochrona przed DNS rebinding, ścisły CSP,
    • dziennik zdarzeń.
  • Kolejka maili: zgłoszenie i maile zapisują się w jednej transakcji. Ponowienia od 1 min do 24 h, globalny limit maili na godzinę.
  • Wdrożenie: utwardzony unit systemd, install.sh, filtr fail2ban, retencja danych w dniach.

Instalacja

# Linux x86-64 (dla ARM pobierz formd-linux-arm64)
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.1.0/formd-linux-amd64
curl -LO https://github.com/dc9-dev/formd/releases/download/v0.1.0/SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS
sudo install -m 0755 formd-linux-amd64 /usr/local/bin/formd
formd version   # v0.1.0

Albo ze źródeł: go install github.com/dc9-dev/formd/cmd/formd@v0.1.0 (Go 1.27.2+).

Dalej: Szybki start i HTTPS i reverse proxy.

Aktualizacja

Schemat bazy migruje się sam przy starcie (dochodzą kolumny statusu i oceny zgłoszeń oraz tabela kosztów Jev). Przed aktualizacją zrób kopię formd.db.

Pliki

Plik Platforma
formd-linux-amd64 Linux x86-64, statycznie linkowana
formd-linux-arm64 Linux ARM64, statycznie linkowana
SHA256SUMS sumy kontrolne

Zbudowane z commita cd96ade przez Go 1.27.2 (CGO_ENABLED=0, -trimpath).