fix: corriger bug multi-sessions (upsertUser wrong ID + schema repair + logs refresh)

- auth.go: upsertUser utilise toujours SELECT explicite au lieu de LastInsertId()
  qui retournait un rowid obsolète pour ON CONFLICT DO UPDATE sur ligne existante
- auth.go: vérifier l'erreur de l'INSERT refresh_tokens (était silencieusement ignorée)
- auth.go: logs détaillés dans Refresh handler pour diagnostiquer les 401
- db.go: repairSchema() ajoute les colonnes manquantes (ip, last_used_at) dans les
  bases où migration 002 était partiellement appliquée (ancien bug multi-statements)
- app.js: tryRefresh et fetchMe affichent le vrai message d'erreur du backend

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
enzo 2026-03-22 01:32:01 +01:00
parent dc0c67b89c
commit 95757124de
3 changed files with 88 additions and 19 deletions

View file

@ -53,6 +53,11 @@ func Open(dataDir string) (*DB, error) {
return nil, fmt.Errorf("migrations : %w", err)
}
// Réparer les colonnes manquantes (bases créées avant le fix multi-statements)
if err := db.repairSchema(); err != nil {
return nil, fmt.Errorf("réparation schéma : %w", err)
}
return db, nil
}
@ -191,3 +196,51 @@ func (db *DB) IsInstalled() (bool, error) {
}
return v == "true", nil
}
// repairSchema ajoute les colonnes manquantes dans les bases créées avant le fix
// multi-statements des migrations. Migration 002 était partiellement appliquée
// (seul user_agent ajouté) sur les bases existantes.
func (db *DB) repairSchema() error {
type col struct {
table, name, def string
}
needed := []col{
{"refresh_tokens", "user_agent", "TEXT NOT NULL DEFAULT ''"},
{"refresh_tokens", "ip", "TEXT NOT NULL DEFAULT ''"},
{"refresh_tokens", "last_used_at", "DATETIME"},
}
for _, c := range needed {
if err := db.ensureColumn(c.table, c.name, c.def); err != nil {
return err
}
}
return nil
}
// ensureColumn ajoute une colonne à une table si elle n'existe pas déjà.
func (db *DB) ensureColumn(table, column, definition string) error {
rows, err := db.Query(fmt.Sprintf("PRAGMA table_info(%s)", table))
if err != nil {
return fmt.Errorf("PRAGMA table_info(%s) : %w", table, err)
}
defer rows.Close()
for rows.Next() {
var cid int
var name, colType string
var notNull, pk int
var dflt sql.NullString
if err := rows.Scan(&cid, &name, &colType, &notNull, &dflt, &pk); err != nil {
return err
}
if name == column {
return nil // déjà présente
}
}
if err := rows.Err(); err != nil {
return err
}
_, err = db.Exec(fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s %s", table, column, definition))
return err
}