b2894fca70
- Create register and login use cases - Implement JWT service for token generation and validation - Add authentication middleware to protect habit endpoints - Create auth HTTP handlers (register, login) - Update habit handlers to extract userID from JWT token - Register/login endpoints: POST /auth/register, POST /auth/login - Habit endpoints now require Bearer token in Authorization header - Tested: register -> create habit -> list habits works correctly
51 lines
1.0 KiB
Go
51 lines
1.0 KiB
Go
package queries
|
|
|
|
import (
|
|
"context"
|
|
|
|
"habit-tracker-api/internal/domain/repositories"
|
|
"habit-tracker-api/internal/shared/errors"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type LoginUserQuery struct {
|
|
Email string
|
|
Password string
|
|
}
|
|
|
|
type LoginUserResult struct {
|
|
UserID string
|
|
Email string
|
|
Timezone string
|
|
}
|
|
|
|
type LoginUserHandler struct {
|
|
userRepo repositories.UserRepository
|
|
}
|
|
|
|
func NewLoginUserHandler(userRepo repositories.UserRepository) *LoginUserHandler {
|
|
return &LoginUserHandler{userRepo: userRepo}
|
|
}
|
|
|
|
func (h *LoginUserHandler) Handle(ctx context.Context, query LoginUserQuery) (*LoginUserResult, error) {
|
|
if query.Email == "" || query.Password == "" {
|
|
return nil, errors.ErrInvalidInput
|
|
}
|
|
|
|
user, err := h.userRepo.FindByEmail(ctx, query.Email)
|
|
if err != nil {
|
|
return nil, errors.ErrNotFound
|
|
}
|
|
|
|
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(query.Password)); err != nil {
|
|
return nil, errors.ErrNotFound
|
|
}
|
|
|
|
return &LoginUserResult{
|
|
UserID: user.ID,
|
|
Email: user.Email,
|
|
Timezone: user.Timezone,
|
|
}, nil
|
|
}
|