package usecase import ( "context" "errors" "strings" "time" "github.com/golang-jwt/jwt/v5" "golang.org/x/crypto/bcrypt" ) // Login validates credentials using username and returns a signed JWT. func (s *Service) Login(ctx context.Context, username, password string) (string, time.Time, error) { if strings.TrimSpace(username) == "" { return "", time.Time{}, errors.New("username is required") } user, err := s.repo.GetUserByUsername(ctx, username) 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") } expiresAt := time.Now().Add(s.tokenTTL) claims := jwt.MapClaims{ "user_id": user.ID.String(), "company_id": user.CompanyID.String(), "role": user.Role, } signed, err := s.signToken(claims, expiresAt) if err != nil { return "", time.Time{}, err } return signed, expiresAt, nil }