diff --git a/internal/models/sessions.go b/internal/models/sessions.go index a025557b54..92580d365a 100644 --- a/internal/models/sessions.go +++ b/internal/models/sessions.go @@ -351,7 +351,7 @@ func updateFactorAssociatedSessions(tx *storage.Connection, userID, factorID uui } func InvalidateSessionsWithAALLessThan(tx *storage.Connection, userID uuid.UUID, level string) error { - return tx.RawQuery("DELETE FROM "+(&pop.Model{Value: Session{}}).TableName()+" WHERE user_id = ? AND aal < ?", userID, level).Exec() + return tx.RawQuery("DELETE FROM "+(&pop.Model{Value: Session{}}).TableName()+" WHERE user_id = ? AND (aal IS NULL OR aal < ?)", userID, level).Exec() } // Logout deletes all sessions for a user. diff --git a/internal/models/sessions_test.go b/internal/models/sessions_test.go index 77794874c8..03fb82a570 100644 --- a/internal/models/sessions_test.go +++ b/internal/models/sessions_test.go @@ -57,6 +57,36 @@ func (ts *SessionsTestSuite) TestFindBySessionIDWithForUpdate() { require.Equal(ts.T(), session.ID, found.ID) } +func (ts *SessionsTestSuite) TestInvalidateSessionsWithAALLessThan() { + u, err := FindUserByEmailAndAudience(ts.db, "test@example.com", ts.Config.JWT.Aud) + require.NoError(ts.T(), err) + + aal1Session, err := NewSession(u.ID, nil) + require.NoError(ts.T(), err) + require.NoError(ts.T(), ts.db.Create(aal1Session)) + + // Simulates a legacy session created before the aal column was backfilled. + legacySession := &Session{ID: uuid.Must(uuid.NewV4()), UserID: u.ID, AAL: nil} + require.NoError(ts.T(), ts.db.Create(legacySession)) + + aal2Session, err := NewSession(u.ID, nil) + require.NoError(ts.T(), err) + aal2Session.AAL = AAL2.PointerString() + require.NoError(ts.T(), ts.db.Create(aal2Session)) + + require.NoError(ts.T(), InvalidateSessionsWithAALLessThan(ts.db, u.ID, AAL2.String())) + + _, err = FindSessionByID(ts.db, aal1Session.ID, false) + require.ErrorIs(ts.T(), err, SessionNotFoundError{}) + + _, err = FindSessionByID(ts.db, legacySession.ID, false) + require.ErrorIs(ts.T(), err, SessionNotFoundError{}) + + found, err := FindSessionByID(ts.db, aal2Session.ID, false) + require.NoError(ts.T(), err) + require.Equal(ts.T(), aal2Session.ID, found.ID) +} + func (ts *SessionsTestSuite) AddClaimAndReloadSession(session *Session, claim AuthenticationMethod) *Session { err := AddClaimToSession(ts.db, session.ID, claim) require.NoError(ts.T(), err)