diff --git a/auth.go b/auth.go index d6161e9..9a179b7 100644 --- a/auth.go +++ b/auth.go @@ -4,7 +4,6 @@ import ( crand "crypto/rand" "database/sql" "encoding/hex" - "math/rand/v2" "net/http" "regexp" "strconv" @@ -27,10 +26,6 @@ var ( reSpace = regexp.MustCompile(`\s+`) ) -// loginJitter ist die Obergrenze (in ms) der zufälligen Login-Verzögerung gegen -// Timing-Angriffe. Tests setzen den Wert auf 0, um die Verzögerung abzuschalten. -var loginJitter = 2000 - // getSession liest den session-Cookie und liefert die zugehörige, noch gültige Session. func getSession(r *http.Request) (*Session, bool) { c, err := r.Cookie("session") @@ -70,12 +65,6 @@ func handleLogin(w http.ResponseWriter, r *http.Request) { var uid int64 var hash []byte err := db.QueryRow(`SELECT uid, password FROM user WHERE username = ?`, username).Scan(&uid, &hash) - - // Gegen Timing-Angriffe: immer eine kleine, zufällige Verzögerung. - if loginJitter > 0 { - time.Sleep(time.Duration(rand.IntN(loginJitter)) * time.Millisecond) - } - if err == sql.ErrNoRows { writeError(w, http.StatusUnauthorized, "Nutzername oder Passwort ist falsch.") return diff --git a/endpoints_test.go b/endpoints_test.go index 037abf7..8f7b87a 100644 --- a/endpoints_test.go +++ b/endpoints_test.go @@ -16,8 +16,6 @@ import ( func newTestServer(t *testing.T) *httptest.Server { t.Helper() - loginJitter = 0 // Login-Verzögerung in Tests abschalten - dsn := filepath.Join(t.TempDir(), "test.db") if err := initDB(dsn); err != nil { t.Fatalf("initDB: %v", err) diff --git a/entry.go b/entry.go index 393f075..0856e78 100644 --- a/entry.go +++ b/entry.go @@ -75,16 +75,16 @@ func handleCreateEntry(w http.ResponseWriter, r *http.Request) { content = content[:1000] } - filepath := "none" + filepath := "" if r.MultipartForm != nil { if files := r.MultipartForm.File["file"]; len(files) > 0 { - if stored, err := storeImage(files[0]); err == nil && stored != "" { + if stored, err := storeImage(files[0]); err == nil { filepath = stored } } } - if filepath == "none" && content == "" { + if filepath == "" && content == "" { writeError(w, http.StatusBadRequest, "Leerer Beitrag!") return } diff --git a/notes/migrations.md b/notes/migrations.md new file mode 100644 index 0000000..53b1e4d --- /dev/null +++ b/notes/migrations.md @@ -0,0 +1,24 @@ +# Datenbank-Migrationen + +Manuelle Schritte, die beim Deploy gegen eine **bestehende** Datenbank nötig sind. +Eine frische DB (Schema aus `db.go`) braucht keine davon. + +--- + +## `filepath`-Sentinel `"none"` → leerer String + +**Wann:** beim Umstieg auf die Go-Version, falls eine alte `kver.db` aus der +Python-Zeit weiterverwendet wird. + +**Hintergrund:** Die Python-Version schrieb für Beiträge ohne Bild den +String `"none"` in `entry.filepath`. Die Go-Version nutzt stattdessen den +leeren String (Go-Zero-Value) und prüft nur noch auf `filepath == ""`. +Alte `"none"`-Zeilen würden sonst im Feed als Bildpfad interpretiert +(`` → kaputtes Bild). + +**Migration:** +```sql +UPDATE entry SET filepath = '' WHERE filepath = 'none'; +``` + +Idempotent — kann gefahrlos mehrfach laufen. diff --git a/user.go b/user.go index e768f21..dd3c36f 100644 --- a/user.go +++ b/user.go @@ -94,7 +94,7 @@ func handleUserDelete(w http.ResponseWriter, r *http.Request) { if rows, err := db.Query(`SELECT filepath FROM entry WHERE uid = ?`, uid); err == nil { for rows.Next() { var fp string - if rows.Scan(&fp) == nil && fp != "" && fp != "none" { + if rows.Scan(&fp) == nil && fp != "" { media = append(media, fp) } } diff --git a/web/js/app.js b/web/js/app.js index 4d6acc6..1e20c60 100644 --- a/web/js/app.js +++ b/web/js/app.js @@ -75,7 +75,7 @@ function renderEntry(e) { const when = new Date(e.created_at * 1000).toLocaleString("de-DE"); let media = ""; - if (e.filepath && e.filepath !== "none") { + if (e.filepath) { media = ``; }