Commit Graph

13 Commits

Author SHA1 Message Date
irrlicht c4a0c5c378 Datenschutz + Notes: Reichweitenmessung dokumentieren
Punkt 5 beschreibt die anonyme Reichweitenmessung inkl. ASN-Einordnung;
durchgaengig "anonymisierte IP-Adresse" und expliziter Hinweis, dass auch
fuer die ASN-Bestimmung nie die volle IP verwendet wird. IPv6-
Anonymisierung auf /32 (letzte 96 Bit) korrigiert.

Notes: Migration der asn-Spalte (ALTER TABLE) und neue Env-Var
KVER_GEOIP_ASN samt GeoLite2-Bereitstellung.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:21:17 +02:00
irrlicht 8d9bcd08ea deploy.md: Caddy-Config, Port 7777, Upload-Anleitung überarbeitet
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 20:11:38 +02:00
irrlicht 99cc1f0ebb deploy.md: Healthcheck in Quadlet-Unit statt Containerfile (OCI kennt kein HEALTHCHECK)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 19:54:58 +02:00
irrlicht 50be342899 Deployment-Härtung + Podman-Container
- http.Server mit Timeouts (Slowloris) und Graceful Shutdown (SIGTERM)
- Adresse und DB-Pfad per Env (KVER_ADDR, KVER_DB)
- Security-Header global: nosniff, X-Frame-Options, Referrer-Policy, CSP
- Upload-Requests hart auf 17 MB gedeckelt (MaxBytesReader statt nur
  Multipart-Speichergrenze)
- Indizes für Feed-, Thread- und Vote-Queries
- middleware.RealIP für Logging/Rate-Limit hinter dem Reverse-Proxy
- Containerfile (Multi-Stage, Alpine, non-root) + Deploy-Doku in notes/

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 07:00:09 +02:00
irrlicht 15ef7db5f7 Profilbilder: Avatar-Upload, Anzeige auf Profil & Feed
- user.avatar-Spalte (Schema, migrate.sh, Migrationsdoku)
- POST /user/avatar (geschützt): Upload via storeImage, ersetzt/löscht altes Bild
- avatar in /u/{name}/info, /user/info und im entrySelect-Join (Feed-Karten)
- Account-Löschung entfernt auch das Avatar-File
- Frontend: Avatar im Profilkopf + Byline der Karten (50px), Upload-Form,
  Platzhalterbild no_profile_pic.jpg als Fallback
- .card img per :not(.avatar) von Beitragsbildern getrennt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 18:20:14 +02:00
irrlicht 5478e92253 Migration, Schema-NOT-NULL & klickbare Karten
migrate.sh erzeugt nicht-destruktiv eine frische kver.db aus original-kver.db
mit dem aktuellen Go-Schema (NULL/'none'-filepath normalisiert, Soft-Deletes
und Waisen verworfen). Das entry-Schema erzwingt jetzt NOT NULL DEFAULT '' auf
content/filepath – NULL-filepath ließ scanEntries Zeilen still überspringen.
Feed-Karten sind per Klick navigierbar (mit Hover-Highlight); DB-Artefakte
landen im .gitignore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 17:07:05 +02:00
irrlicht cb3da3bb24 Soft-Delete: Beiträge als [deleted] erhalten statt löschen
- entry.deleted; entrySelect LEFT JOIN + COALESCE(username)
- POST /entry/{pid}/delete: deleted=1, Inhalt/Bild/Autor geleert, Zeile bleibt
- Konto-Löschung soft-deletet die eigenen Beiträge (statt hartem DELETE),
  damit fremde Antworten nicht verwaisen
- Frontend: [deleted]-Platzhalter im Feed, Löschen-Button auf Focus-Seite
- notes/migrations.md: ALTER TABLE deleted

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 13:21:42 +02:00
irrlicht ba085eff4e Threading: Antworten (reply_to) + Focus-View
- entry: reply_to/reply_count/last_activity; reply_count bubbelt bis Root
- Hauptfeed nur Roots nach last_activity, Profil-Feed inkl. Antworten
- GET /entry/{pid}/thread (Ahnen+Antworten), GET /e/{pid} Focus-Seite
- Frontend: Antworten-Link im Feed, entry.html/entry.js Focus-Seite
- notes/migrations.md: ALTER TABLE fuer Prod

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 12:21:55 +02:00
irrlicht e210df3e2e Code-Cleanup: toter Check, none-Sentinel, Login-Jitter raus
- entry.go: redundantes stored != "" entfernt
- filepath-Sentinel "none" -> leerer String (Go-Zero-Value),
  Checks in entry.go/user.go und web/js/app.js vereinfacht
- auth.go: zufaelligen Login-Jitter samt loginJitter-Variable und
  Test-Seam entfernt (war nur Spielerei, kein echter Schutz)
- notes/migrations.md: einmalige "none"->"" Migration dokumentiert

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 11:33:41 +02:00
irrlicht 38da498754 Split voting into clean read/write endpoints
Replaces the GET-mutates-state interactions route with a proper split:
- GET  /entry/{pid}/votes  reads the tally (public, read-only)
- POST /entry/{pid}/vote   casts/toggles the vote (auth, mode in body)

Shared voteTally/writeTally helpers back both handlers. Invalid mode now
returns 400. Frontend updated to read via GET and vote via POST.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 11:03:33 +02:00
irrlicht be8dbb4902 Implement left/right voting on entries
GET /entry/{pid}/interactions/{mode} now reads the vote tally and, for
mode=left/right (auth required), toggles the user's vote: new vote, repeat
same mode removes it, different mode switches. Returns {left, right,
selected}. A UNIQUE(uid, pid) constraint on the vote table prevents
duplicate votes. The JS frontend renders Links/Rechts buttons with live
counts under each entry.

This completes the voting feature that was left commented-out and broken
in the Flask version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 10:58:58 +02:00
irrlicht c904e3e2db Implement user account deletion flow
POST /user/delete (auth required) verifies the password via pass1 and
transactionally removes the user's sessions, votes, entries and the user
row, then clears the session cookie. Associated media files are removed
best effort after commit. This was only a stub in the Flask original.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 10:19:29 +02:00
irrlicht cb237c248e Rewrite backend in Go with JSON API and JS frontend
Reimplements the Flask app as a Go HTTP API (chi + modernc sqlite) with a
minimal vanilla-JS frontend in web/. Endpoints mirror the original Flask
routes but return JSON instead of HTML.

- auth: login/logout/register/sessioninfo/headerbar with crypto/rand tokens
- entry: paginated feed (single JOIN), create with image scaling
- user: profile, userinfo; delete still a stub
- requireAuth middleware passes uid via context
- notes/api.md documents the API and schema

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 10:17:02 +02:00