package usecase import ( "context" "errors" "strings" "time" "golang.org/x/crypto/bcrypt" ) // Login validates credentials using username or email and returns a signed JWT. func (s *Service) Login(ctx context.Context, identifier, password string) (string, time.Time, error) { if strings.TrimSpace(identifier) == "" { return "", time.Time{}, errors.New("identifier is required") } // Try fetching by username first user, err := s.repo.GetUserByUsername(ctx, identifier) if err != nil { // Try fetching by email user, err = s.repo.GetUserByEmail(ctx, identifier) if err != nil { return "", time.Time{}, errors.New("invalid credentials") } } if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(s.pepperPassword(password))); err != nil { return "", time.Time{}, errors.New("invalid credentials") } return s.issueAccessToken(user) }