fix: Login-userId war nicht stabil gegenüber Groß-/Kleinschreibung
/api/auth/login mintete die JWT-userId bisher aus dem roh eingegebenen Benutzernamen. LiteDBs Standard-Collation vergleicht den eindeutigen Index auf Username aber case-insensitive - ein Login mit nur einmal abweichender Schreibweise auf einem zweiten Gerät authentifiziert erfolgreich, mintet aber eine andere userId. Da EventStore.GetCol(userId) diese direkt als Dateiname für den Server-seitigen Event-Speicher nutzt, entstanden zwei komplett getrennte Datenbestände für ein und dasselbe, aus Nutzersicht einzige Konto - Ursache dafür, dass ein zweites Gerät trotz "since=0" durchgängig 0 Ereignisse erhielt. UserStore.VerifyPassword(bool) durch Authenticate(UserEntry?) ersetzt, das bei Erfolg den kanonisch gespeicherten Nutzereintrag liefert; /api/auth/login mintet Token und userId daraus statt aus der Roheingabe. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,7 @@ public sealed class UserStoreTests
|
||||
var created = temp.Store.CreateUser("sebastian", "einSicheresPasswort");
|
||||
|
||||
Assert.True(created);
|
||||
Assert.True(temp.Store.VerifyPassword("sebastian", "einSicheresPasswort"));
|
||||
Assert.NotNull(temp.Store.Authenticate("sebastian", "einSicheresPasswort"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -27,20 +27,40 @@ public sealed class UserStoreTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyPassword_FalschesPasswort_GibtFalseZurueck()
|
||||
public void Authenticate_FalschesPasswort_LiefertNull()
|
||||
{
|
||||
using var temp = new TempUserStore();
|
||||
temp.Store.CreateUser("sebastian", "einSicheresPasswort");
|
||||
|
||||
Assert.False(temp.Store.VerifyPassword("sebastian", "falschesPasswort"));
|
||||
Assert.Null(temp.Store.Authenticate("sebastian", "falschesPasswort"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyPassword_UnbekannterNutzer_GibtFalseZurueck()
|
||||
public void Authenticate_UnbekannterNutzer_LiefertNull()
|
||||
{
|
||||
using var temp = new TempUserStore();
|
||||
|
||||
Assert.False(temp.Store.VerifyPassword("unbekannt", "irgendwas"));
|
||||
Assert.Null(temp.Store.Authenticate("unbekannt", "irgendwas"));
|
||||
}
|
||||
|
||||
/// Regression: LiteDBs Standard-Collation vergleicht den eindeutigen Index auf Username
|
||||
/// case-insensitive - ein Login mit abweichender Groß-/Kleinschreibung authentifiziert also
|
||||
/// erfolgreich. Würde der Aufrufer (Endpoints./api/auth/login) daraufhin den roh eingegebenen
|
||||
/// Namen statt des kanonisch gespeicherten als userId für den Server-seitigen Event-Speicher
|
||||
/// verwenden, würde ein einziger andersartig getippter Login auf einem zweiten Gerät einen
|
||||
/// komplett getrennten, nicht überlappenden Datenbestand erzeugen (siehe TODO 10.2.5 - genau
|
||||
/// das vom Nutzer beobachtete Symptom: nur ein Konto im System, aber Client 2 erhielt trotz
|
||||
/// since=0 keine Ereignisse).
|
||||
[Fact]
|
||||
public void Authenticate_AndereGrossKleinschreibung_LiefertDenKanonischGespeichertenNamen()
|
||||
{
|
||||
using var temp = new TempUserStore();
|
||||
temp.Store.CreateUser("sebastian", "einSicheresPasswort");
|
||||
|
||||
var user = temp.Store.Authenticate("Sebastian", "einSicheresPasswort");
|
||||
|
||||
Assert.NotNull(user);
|
||||
Assert.Equal("sebastian", user!.Username);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -52,8 +72,8 @@ public sealed class UserStoreTests
|
||||
var updated = temp.Store.SetPassword("sebastian", "neuesPasswort123");
|
||||
|
||||
Assert.True(updated);
|
||||
Assert.True(temp.Store.VerifyPassword("sebastian", "neuesPasswort123"));
|
||||
Assert.False(temp.Store.VerifyPassword("sebastian", "altesPasswort123"));
|
||||
Assert.NotNull(temp.Store.Authenticate("sebastian", "neuesPasswort123"));
|
||||
Assert.Null(temp.Store.Authenticate("sebastian", "altesPasswort123"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
Reference in New Issue
Block a user