joetjen.net
EN DE
Anwendung

Was Lictor 0.2 kann

Lictor 0.2.0, veröffentlicht am 19. Oktober 2026 mit Praxis v0.63.0, liefert seine Website aus und lässt jemanden per Einladung herein. Alles auf dieser Seite lief gegen dieses Release.

In Entwicklung · v0.2

Starten

Aus dem Verzeichnis lictor/ des Repositorys:

LICTOR_PORT=4123 LICTOR_BASE_URL=http://localhost:4123 prx run --sname lictor --no-halt
tailwind: stylesheet built
posthorn mailbox on http://localhost:64064
lictor: development admin seeded -- log in as admin, password admin. This account exists in development only: any other environment refuses it.
lictor listening on http://localhost:4123

Zwei Adressen: die Website, auf LICTOR_PORT (4000, wenn nichts anderes gesagt ist; dieser Lauf wählte 4123), und das Entwicklungs-Postfach, auf einem Port, den das System gerade frei hatte. --no-halt hält den Server am Laufen, nachdem main zurückgekehrt ist; --sname lictor macht die Instanz zu einem Knoten, über den prx lictor invite sie erreicht. In der Entwicklung wird ein Admin, admin/admin, angelegt und angekündigt — und jede andere Umgebung startet nicht, wenn er eingeschaltet ist.

Registrierung per Einladung

Die Beta ist nur auf Einladung, und die Registrierung erreicht man über eine Einladung und sonst nichts — es gibt kein /register. In einem zweiten Terminal:

prx lictor invite Ada Lovelace
http://localhost:4123/invite/WPt3PZvpeo3FLslP6ugrKtO55X74XI7F2wkM_23G-Tc

Das laufende Lictor erzeugt den Link: Solange die Konten im Speicher liegen, gibt es eine Einladung nur in der Instanz, die sie erzeugt hat, deshalb tritt der Task deren Knoten bei und fragt dort Kether. Der Link funktioniert einmal, und eine Woche lang.

  • GET /invite/<token> zeigt das Formular: ein Benutzername, eine E-Mail-Adresse, ein Passwort mit mindestens zwölf Zeichen. Das Aufrufen verbraucht die Einladung nicht.
  • POST /invite/<token> registriert: „Check your mail“, und eine Nachricht im Postfach. Ein vergebener Benutzername, eine schon registrierte Adresse, ein Benutzername, der eine Adresse ist, oder ein zu kurzes Passwort beantworten das Formular erneut mit 422, mit dem betroffenen Feld — und schreiben das Passwort nie zurück.
  • GET /verify/<token> — der Link in der Mail, einen Tag gültig — antwortet „Your account is ready“. Ein benutzter, unbekannter oder abgelaufener Einladungs- oder Bestätigungslink antwortet „no longer valid“ mit 410; ein Formular ohne CSRF-Token ist ein 403.

Von Hand gegen 0.2.0 durchgespielt: Das Formular mit einem fünfstelligen Passwort ergab 422 mit „A password needs at least 12 characters.“, eine Adresse als Benutzername 422 mit „A username cannot be an email address.“, ein korrektes Formular „Check your mail“; der erneut geöffnete Einladungslink ergab danach 410, der gemailte Link „Your account is ready“, derselbe Link noch einmal 410, und /register 404.

Das Entwicklungs-Postfach

Nichts wird verschickt. Jede Mail, die das laufende Lictor senden würde, behält das Entwicklungs-Postfach von posthorn und listet sie, neueste zuerst, auf der Seite, die prx run ausgegeben hat — nur auf 127.0.0.1, jede Mail öffnet sich zu ihrem Text mit dem Bestätigungslink darin. prx posthorn --node lictor liefert dieselbe Seite aus einem anderen Terminal; das Postfach wird gefunden, weil es sich beim Start selbst bekannt macht.

Routen

Die Routen sind Daten in lictor.elysium, und prx routes liest die Tabelle zurück:

prx routes lictor.elysium
GET   /               lictor.elysium/front-page
GET   /invite/:token  lictor.elysium/invite-form
POST  /invite/:token  lictor.elysium/register
GET   /verify/:token  lictor.elysium/verify-address
POST  /theme          lictor.elysium/choose-theme

Alles andere ist ein 404. /assets/ liefert das Stylesheet, das Siegel und die Icons. POST /theme nimmt „light“, „dark“ oder „system“, ein Jahr lang in einem Cookie gespeichert, ohne JavaScript; „system“ folgt dem Browser.

Konfiguration

Die Konfiguration ist CASC, config/config.casc, mit einer Ergänzung je Umgebung, gelesen von cooper_prx, bevor main läuft. Jede Anwendung liest ihren eigenen Block und keinen anderen:

config/config.casc
#@version = 1.0

lictor_elysium {
  port = "${LICTOR_PORT:4000}"
  base-url = "${LICTOR_BASE_URL:http://localhost:4000}"
  mail-from = "lictor@localhost"
}

lictor_kether {
}

import "${PRX_ENV:dev}/*.casc"
Kether-EinstellungVorgabe
invite-validity604800eine Woche, in Sekunden
verification-validity86400ein Tag
minimum-password12Zeichen
password-iterations600000die PBKDF2-Kosten von shibboleth

Die Kommentare sind oben weggelassen. Die Ergänzung für die Entwicklung nennt die Umgebung und schaltet den Admin ein.

Testen

Jede Etappe beginnt als Abnahmetest, der die Anwendung so fragt, wie es ein Browser täte, ohne Server — mit übergebenem Speicher, Postfach und Uhr, sodass ein Test eine Woche vorspulen kann, ohne darauf zu warten.

apps/lictor_elysium/tests/lictor/elysium-test.prax
(deftest the-site-answers-at-its-root-with-a-page-that-names-lictor
  (let [answer ((elysium/app) (test/request :get "/"))]
    (assert= (:status answer) 200)
    (assert (str/contains? (:body answer) "Lictor"))))
prx test         # the suite's tests
prx precommit    # compile, fmt --check, test
  ok    an-invite-link-leads-to-a-verified-account
  ok    an-invite-works-once
  …
213 test(s), 0 failure(s)