fix: security & privacy (rate limiter fix, csrf session cookie, logout on server, drafts stale token passw, login timing, password over 72b, JWT_SECRET complexity, SMTP TLS, CSV export neutralised, fonts bundled, upload metadata, hourly cleanup job, privacy.md report)

This commit is contained in:
Florian Sylvain committed 2026-10-22 00:49:19 +02:00
1 parent e2812ee0b9
commit ea98c5ec05
118 files changed
+3828 -130

No files matched your search

+27 -6
View File
@@ -106,17 +106,38 @@ func TestAuthenticateUserUseCase(t *testing.T) {
}
})
t.Run("unknown username never calls the hasher", func(t *testing.T) {
t.Run("unknown username spends the same hashing work as a wrong password", func(t *testing.T) {
repo := newMockUserRepo()
hasher := &spyHasher{}
uc := useCases.NewAuthenticateUserUseCase(repo, hasher, discardRecorder)
_, err := uc.Authenticate(testCtx, "bob", "hunter2example")
if !errors.Is(err, user.ErrUserNotFound) {
t.Errorf("expected user.ErrUserNotFound, got %v", err)
for attempt := 1; attempt <= 2; attempt++ {
_, err := uc.Authenticate(testCtx, "bob", "hunter2example")
if !errors.Is(err, user.ErrUserNotFound) {
t.Errorf("attempt %d: expected user.ErrUserNotFound, got %v", attempt, err)
}
if hasher.compareCalls != attempt {
t.Errorf("attempt %d: expected %d Compare calls, got %d", attempt, attempt, hasher.compareCalls)
}
}
if hasher.compareCalls != 0 {
t.Errorf("expected the hasher's Compare to never be called, got %d calls", hasher.compareCalls)
if hasher.hashCalls != 1 {
t.Errorf("expected the decoy to be hashed once, got %d Hash calls", hasher.hashCalls)
}
})
t.Run("a repository failure other than not-found skips the decoy", func(t *testing.T) {
repo := newMockUserRepo()
repo.fail.failNextWith("GetByUsername", errStubHashFailure)
hasher := &spyHasher{}
uc := useCases.NewAuthenticateUserUseCase(repo, hasher, discardRecorder)
_, err := uc.Authenticate(testCtx, "bob", "hunter2example")
if !errors.Is(err, errStubHashFailure) {
t.Errorf("expected the repository error, got %v", err)
}
if hasher.compareCalls != 0 || hasher.hashCalls != 0 {
t.Errorf("expected no hashing, got %d Compare and %d Hash calls", hasher.compareCalls, hasher.hashCalls)
}
})
}