Commit Graph
114 Commits
Author SHA1 Message Date
irrlichtandClaude Opus 5.5 07a2b64eff Statistik: tägliche SVG-Diagramme statt CSS-Balken
Der Server rendert einmal täglich (0:01 Uhr deutscher Zeit) Liniendiagramme
für Aufrufe, Netze und Beiträge pro Tag sowie gestapelte Säulen (Threads/
Antworten) für den Ø pro Wochentag und pro Tageszeit, je schmal (600) und
breit (1200), ausgeliefert über /api/stats/charts. Hovern zeigt den
Datenpunkt in einer Infozeile und markiert ihn mit einer senkrechten Linie.

Die Statistik-Seite wird auf breiten Bildschirmen bis 1200 px breit.
"Netze nach Betreiber" entfällt; neu ist die Kennzahl Ø Beiträge/Tag der
letzten 30 Tage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-10-06 20:13:30 +02:00
irrlichtandClaude Opus 5.5 047ad392d9 Datenschutz: Anonymisierung nicht absolut versprechen
Mit Zusatzwissen ließ sich ein Netz aus der Reichweitenmessung einer
Person zuordnen. Die Erklärung sagt deshalb nur noch, dass einzelne
Personen in der Regel nicht bestimmbar sind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-10-06 19:37:18 +02:00
irrlichtandClaude Opus 5.5 26b0182391 Linkvorschau für den ersten Link eines Beitrags
Der Server holt zum ersten Link Titel, Seiten- bzw. Kanalname und ein
kleines Vorschaubild (320 px) und speichert das Bild lokal; der Browser
lädt nur von uns, Besucher-IPs gehen nie an die verlinkte Seite.
YouTube über oEmbed (alle Linkformen kanonisch als watch?v=<id>), alle
übrigen Seiten über OpenGraph bzw. <title>. Abruf asynchron in einem
Worker, eine Zeile je Link in link_preview, Auffrischen nach 30 Tagen.

Der Abruf-Client lässt nur öffentliche IPs auf Port 80/443 zu, geprüft
nach DNS-Auflösung und bei jeder Weiterleitung (SSRF). Bestehende
Beiträge: kver link-previews. Neue Abhängigkeit golang.org/x/net, damit
go 1.26. DEV bekommt ein beschreibbares Volume für die Vorschaubilder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-10-06 18:47:21 +02:00
irrlichtandClaude Opus 5.5 a8f392edba Plan Android-App (notes/android.md)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-10-06 18:47:21 +02:00
irrlichtandClaude Opus 5.5 764ad50b8e Passwort-Reset: Review-Fixes
- Token vor bcrypt prüfen, damit beliebige Tokens keine CPU-Last erzeugen
- CLI meldet DB-Fehler nicht mehr als "Nutzer nicht gefunden"
- Reset in einem Browser mit fremder Session räumt diese mit ab
- Konto-Löschen entfernt auch offene Reset-Links

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 00:44:32 +02:00
irrlichtandClaude Opus 5.5 81a74375b7 Passwort-Reset per Einmal-Link (kver reset-link)
Ohne E-Mail-System erzeugt der Admin per CLI einen Link (/reset#<token>),
gültig 72 h und einmal. Gespeichert wird nur der SHA-256 des Tokens; es
steht im Fragment und geht nur im POST-Body an die API. Der Reset meldet
alle alten Sessions ab und loggt direkt neu ein. Passwortregeln jetzt
gemeinsam in checkNewPassword.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:56:05 +02:00
irrlichtandClaude Opus 5.5 b6cf8c7fa0 Abstimmung Ja/Nein statt Links/Rechts
Modus-Werte yes/no statt left/right in DB, API und Statistik; Knöpfe
"Ja"/"Nein". Bestehende Stimmen müssen per SQL migriert werden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-29 18:14:57 +02:00
irrlichtandClaude Opus 5.5 3d2447fe35 Melden rechts in der Byline jeder Karte, auch anonym
- Melden-Knopf in der Byline aller Beiträge (außer eigenen), Grund-Formular
  darunter; ersetzt den Knopf unter dem fokussierten Beitrag
- /api/entry/{pid}/report öffentlich, 10/min pro IP; ohne Session anonym
  (uid 0), Doppelmeldungen nur für Angemeldete unterdrückt
- Klicks in Formularen öffnen die Karte nicht mehr

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-29 18:05:54 +02:00
irrlichtandClaude Opus 5.5 80c333cd58 Melden-Button: Beiträge mit optionalem Grund melden
- report-Tabelle wieder im Schema (kompatibel zur bestehenden auf PROD)
- POST /api/entry/{pid}/report, nur angemeldet, speichert Melder-uid;
  erneutes Melden legt keine zweite offene Meldung an
- "Melden" auf der Beitragsseite für fremde, nicht gelöschte Beiträge
- Test und API-Doku

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-29 17:53:10 +02:00
irrlichtandClaude Opus 5.5 2bae608d76 Sigillen der Beitragsordnung wieder auf 50px (#sigils zurück)
Die Regel war im Code-Review fälschlich als tot entfernt worden.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-27 15:17:33 +02:00
irrlichtandClaude Opus 5.5 43c640dee6 Rechtstexte wieder gestylt: als Vite-Einstiege mit app.css gebaut
Die Seiten verlinkten /css/app.css, das es seit dem React-Umbau nicht mehr
gibt. Jetzt liegen sie unter frontend/static/docs, Vite baut sie mit und
schreibt den Link auf das gehashte app.css um; serveDoc liefert sie unter
den bisherigen Adressen /static/docs/… aus web/ aus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-27 15:14:53 +02:00
irrlichtandClaude Opus 5.5 df0cfec132 Code-Review: tote Stellen entfernt, Umwege vereinfacht
- SQLite-Import, migrate.sh, notes/migrations.md und altes jQuery-Skript entfernt
- Backend: scanEntry/queryEntries statt doppelter Scan-Liste, Feed-Queries
  direkt statt feedWhere, Thread ohne Map-Umweg, gemeinsame Helfer für
  Cookie-Löschen und Mediennamen, usernameTaken
- Frontend: PostForm für Beitrag und Antwort, EntryCard in Deleted/LiveCard
  aufgeteilt, tote CSS-Regeln und Typen entfernt, Strich-Regeln zusammengelegt
- Rechtstexte verlinken /stats; Kommentare ohne Vorgeschichte

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-27 15:03:22 +02:00
irrlicht d1bd0f5f1d Updated docs 2026-09-27 01:03:15 +02:00
irrlichtandClaude Opus 5.5 4616e8acbb Diskussionsketten: "k weitere Beiträge" als Button im Strich
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-27 01:02:34 +02:00
irrlichtandClaude Opus 5.5 ade853f560 Diskussionsketten: jüngste Antwort im Teilbaum an Feed- und Antwortkarten
Jede Karte in Feed und Antwortliste zeigt die Antwort, die ihre Diskussion
zuletzt fortgesetzt hat: [Beitrag] -- "k weitere Beiträge" -- [Antwort].
Gelöschte Beiträge werden als jüngste übersprungen, zählen auf dem Pfad mit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-27 00:52:17 +02:00
irrlichtandClaude Opus 5.5 8e79e94bbb Login: Zeilenumbruch vor "Einloggen"; dev-up.sh: Lock nicht an conmon vererben
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-27 00:17:31 +02:00
irrlichtandClaude Opus 5.5 4e0d27c4a6 dev-up.sh: DEV-Container neu bauen und starten, auch als post-commit-Hook
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-27 00:10:01 +02:00
irrlichtandClaude Opus 5.5 9a7282ed1d Login: Sitzungsdauer wählbar (1 Stunde bis 1 Jahr)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-27 00:04:07 +02:00
irrlichtandClaude Opus 5.5 9cac33d167 React-Frontend ausliefern, altes Vanilla-Frontend entfernt
- frontend.go: Seitenrouten liefern die index.html (no-cache), gehashte
  Assets unter /assets dauerhaft cachebar, sonst echtes 404
- /stats als Seite, /stats.html leitet per 301 weiter
- Containerfile: Node-Stage baut das Frontend nach web/
- Vite baut nach ../web (gitignored); web/ (Vanilla-JS) gelöscht
- notes/frontend.md, deploy.md angepasst

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 23:49:20 +02:00
irrlichtandClaude Opus 5.5 728ac9b45e React-Frontend: Profilseite und Statistik, Dev-Proxy-Fix
- UserPage mit Profilkopf, Einstellungen (Avatar, Name, Konto löschen)
  und Nutzer-Feed im unveränderten Markup
- StatsPage mit Kacheln und Balken wie bisher
- Feed-Container wählbar (section/div) wie im alten Markup
- Vite-Proxy mit changeOrigin: false -- sonst scheitert jeder POST im
  Dev-Betrieb am Origin-Check

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 23:44:40 +02:00
irrlichtandClaude Opus 5.5 ca65ddcacc React-Frontend: Login, Registrierung, Header, neuer Beitrag
- AuthBox mit Login/Registrierung (Auto-Login nach Registrierung)
- Compose mit Zwischenablage-Bild, Feed springt danach an den Anfang
- Headerbar mit Profil-Link und Logout
- useAuthChanged: me und Votes nach Login/Logout neu laden
- kein Aufblitzen der Login-Box, solange der Anmeldestatus lädt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 23:38:03 +02:00
irrlichtandClaude Opus 5.5 b82c432bce React-Frontend: Thread-Ansicht mit Antworten, Bearbeiten, Löschen
- EntryPage: Vorfahren, Fokus, Antworten mit unverändertem Markup
- Bearbeiten/Löschen für eigene Beiträge, Antwortformular mit
  Zwischenablage-Bild
- useMe(): eigenes Konto oder null (401 = nicht angemeldet)
- nach Änderungen Thread und Feeds invalidieren

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 23:34:31 +02:00
irrlichtandClaude Opus 5.5 bd5c59bcad React-Frontend: Feed mit Beitragskarte, Votes und Repost
- Feed per useInfiniteQuery mit Sentinel-Nachladen, Duplikate gefiltert,
  Stopp an der Backend-Seitengrenze
- EntryCard mit unverändertem Markup (inkl. [deleted]-Platzhalter)
- Votes mit optimistischem Umschalten, Rollback bei Fehler
- Repost mit Cooldown-Anzeige und 429-Auswertung
- linkify ohne innerHTML

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 23:30:17 +02:00
irrlichtandClaude Opus 5.5 37279ac90d React-Frontend: Grundgerüst (Vite, TypeScript, Router, TanStack Query)
- frontend/ mit Vite 8, React 19, React Router 8, TanStack Query 5, TS 7
- api.ts: Fehler allein über HTTP-Status (ApiError), errMsg wie bisher
- types.ts: API-Antworten laut notes/api.md
- Layout mit unverändertem Header-Markup, app.css als Kopie
- Dev-Proxy für /api und /static aufs Go-Backend
- Containerfile: HEALTHCHECK auf /api/stats

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 23:18:56 +02:00
irrlichtandClaude Opus 5.5 030a5bd943 Moderation entfernt, JSON-API unter /api
- Moderationsseite und Melde-Funktion (report) komplett ausgebaut; folgt
  als eigenständiges Projekt
- alle API-Endpunkte unter /api, dort ausschließlich JSON: auch 404, 405,
  Rate-Limit (429) und Panics (500)
- Fehler nur über HTTP-Status; stille DB-Fehler in stats, logout und
  Vote-Zählern liefern jetzt 500 statt Nullen
- /auth/headerbar entfernt (Frontend nutzt /api/user/info)
- Frontend auf /api und statusbasierte Auswertung umgestellt
- notes/api.md neu als Referenz der aktuellen API

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 23:10:02 +02:00
irrlichtandClaude Opus 5.5 2714fdb1a5 Datenbank von SQLite auf Postgres umgestellt
Verbindung über KVER_DSN; Tabelle user heißt jetzt account (reserviertes
Wort in Postgres). kver import-sqlite übernimmt die alte Datei einmalig in
einer Transaktion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 22:22:07 +02:00
irrlichtandClaude Opus 5.5 c6ab082f8c SSR-Renderer entfernt, Fokus auf SPA + JSON-API
Die Kernlogik bleibt von der Schnittstelle getrennt; der letzte SSR-Stand
liegt im Tag ssr-archiv. Die Moderationsseite bleibt, liefert Fehler aber
als JSON.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 21:28:34 +02:00
irrlichtandClaude Opus 5.5 eccddcebe6 SSR: Repost ohne JS, return_to in Formularen, Werbebanner entfernt
Letzter vollständiger SSR-Stand vor dem Rückbau auf reine SPA.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
2026-09-26 21:23:09 +02:00
irrlicht c66df283d1 Umbau-Projekt (SSR und Rest) 2026-09-03 22:20:55 +02:00
irrlicht 13363cb568 Mailadresse aktualisiert 2026-07-01 10:08:34 +02:00
irrlicht e4389de288 Image from clipboard also in replies 2026-06-29 00:16:58 +02:00
irrlicht aa0def2949 Sigils added to rule page 2026-06-28 19:57:52 +02:00
irrlicht ba0d0d62f2 Metaline in deleted posts 2026-06-24 10:24:26 +02:00
irrlicht 32c70ad0f8 New Meta-Line 2026-06-24 10:21:40 +02:00
irrlicht 112e1f82ca Metaline styling 2026-06-24 09:46:10 +02:00
irrlicht 308eec734f Buttons neu sortiert 2026-06-24 09:34:00 +02:00
irrlicht 1cfbb8b8fe Block requests from TOR 2026-06-23 18:26:51 +02:00
irrlicht 01be0c523e Repost 2026-06-22 11:40:27 +02:00
irrlicht e965775809 revert migration 2026-06-19 23:07:18 +02:00
irrlicht 3f05200aeb migration function 2026-06-19 22:53:43 +02:00
irrlicht c30399e498 Fixed /stats layout 2026-06-19 22:49:01 +02:00
irrlichtandClaude Opus 4.8 63240a6cf7 ASN-Auflösung: dominanter Betreiber statt Offset-0-Treffer
Das anonymisierte /16 (bzw. /32 bei IPv6) gehört oft nicht einem
einzigen AS -- gerade im APNIC-Raum ist es in viele kleine Bloecke
zerstueckelt. Der bisherige Lookup auf die Basisadresse lieferte dann
nur den zufaelligen Inhaber von Offset 0 (z.B. faelschlich "Rakuten
Mobile" fuer einen Besucher, der irgendwo im selben /16 sitzt).

Jetzt: per NetworksWithin alle ASNs im Netz zaehlen, das mit der
groessten Adress-Abdeckung waehlen und bei weiteren "(n weitere
Treffer)" anhaengen. Homogene Netze stehen sauber mit Betreibername,
zersplitterte tragen den dominanten plus ehrlichen Unsicherheits-Marker.
Arbeitet weiter ausschliesslich auf dem maskierten Netz, nie auf der
vollen IP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 22:50:33 +02:00
irrlicht 4d99074bd5 Header aktualisiert 2026-06-17 23:58:54 +02:00
irrlichtandClaude Opus 4.8 c55bb07a6d GeoLite2-.mmdb ignorieren
Lizenzierte, sich aendernde Daten -- gehoeren nicht ins Repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:57:33 +02:00
irrlichtandClaude Opus 4.8 dd714762dc Statistik: Impression-Erfassung asynchron (nicht im Request-Pfad)
Der Seitenaufruf wartete bisher synchron auf den DB-Upsert. Mit
synchronous=FULL (WAL) macht SQLite pro Commit ein fsync -> spuerbare
Latenz pro Seitenaufruf. Die Erfassung laeuft jetzt in einer Goroutine,
die Auslieferung blockiert nicht mehr darauf. Der GeoIP-Lookup war nie
das Problem (mmap, einmal beim Start geoeffnet).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:57:33 +02:00
irrlichtandClaude Opus 4.8 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
irrlichtandClaude Opus 4.8 8be8ecedc9 Statistik-Seite: Kennzahlen, Reichweite, ASN und Verlaeufe
Neue Seite /stats.html: Basiszahlen, Reichweite, Netze nach Betreiber
(ASN), Aufrufe pro Tag und beliebteste Seiten. Diagramme als CSS-Balken
(Breite per CSSOM, kein Inline-style) statt Chart-Library -- bleibt
CSP-konform. Verlinkt in der Legal-Nav aller Seiten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:21:17 +02:00
irrlichtandClaude Opus 4.8 662285c8b5 Statistik: anonymes Impression-Tracking mit ASN-Einordnung
Seitenaufrufe werden serverseitig pro (Tag, anonymisiertes Netz, Pfad)
gezaehlt -- nur auf den HTML-Seiten-Routen, nicht auf API/Assets. Die
Client-IP wird sofort maskiert (IPv4 /16, IPv6 /32); die vollstaendige
IP wird nie gespeichert oder weiterverwendet.

Optional loest eine lokale GeoLite2-ASN-DB (Env KVER_GEOIP_ASN) den
Netzbetreiber aus dem bereits anonymisierten Netz auf -- auch dafuer wird
nicht die volle IP herangezogen. Fehlt die DB, bleibt das Feld leer.

Neuer Endpunkt GET /stats/detail liefert die Aggregate; die Tabelle
impression speichert nur Zaehlwerte (kein Eventlog).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:21:17 +02:00
irrlichtandClaude Opus 4.8 bbd4bc27ba Compose: Button "Posten" -> "Eintrag erstellen"
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 14:23:09 +02:00
irrlichtandClaude Opus 4.8 def6a13782 Compose: Bild aus Zwischenablage per Strg+V einfügen
paste-Listener am Formular übernimmt ein Clipboard-Bild in den File-Input
(via DataTransfer), benennt es zu zwischenablage.<ext> und zeigt einen
grauen Hinweis über dem Datei-Input. Kein Bild -> normaler Text-Paste.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 14:22:14 +02:00