Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions internal/auth/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type StoreInterface interface {
GetUserByEmail(ctx context.Context, email string) (*User, error)
CreateUser(ctx context.Context, user *User) error
UpdateUser(ctx context.Context, user *User) error
RecordFailedLogin(ctx context.Context, userID string) error
RecordSuccessfulLogin(ctx context.Context, userID string) error
DeleteUser(ctx context.Context, userID string) error
ListUsers(ctx context.Context) ([]User, error)
GetUserByResetToken(ctx context.Context, token string) (*User, error)
Expand Down
11 changes: 2 additions & 9 deletions internal/auth/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,15 +275,8 @@ func (s *Service) completeSuccessfulLogin(ctx context.Context, user *User) (*Log
return nil, fmt.Errorf("failed to create session: %w", err)
}

now := time.Now()
user.LastLoginAt = &now
user.FailedLoginAttempts = 0
user.LockedUntil = nil
// Deliberately do not return this error: the session was successfully created and the
// token already issued. Failing here would leave the caller with no token despite a
// valid login. The consequence is that LastLoginAt / FailedLoginAttempts may be stale
// in the store until the next successful login, which is an acceptable trade-off.
if err := s.store.UpdateUser(ctx, user); err != nil {
// The session already exists; bookkeeping failure must not hide its token.
if err := s.store.RecordSuccessfulLogin(ctx, user.ID); err != nil {
logging.Warnf("Failed to update login info for user %s: %v", user.ID, err)
}

Expand Down
Loading
Loading