feat: 0.0.1
This commit is contained in:
146 files changed
+10444
No files matched your search
@@ -0,0 +1,138 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
db "github.com/FernandoJVideira/simple_bank/internal/db/sqlc"
|
||||
"github.com/FernandoJVideira/simple_bank/internal/security"
|
||||
"github.com/FernandoJVideira/simple_bank/internal/worker"
|
||||
"github.com/hibiken/asynq"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type userService struct {
|
||||
store db.Store
|
||||
taskDistributor worker.TaskDistributor
|
||||
}
|
||||
|
||||
// NewUserService creates a new user service
|
||||
func NewUserService(store db.Store, taskDistributor worker.TaskDistributor) UserService {
|
||||
return &userService{
|
||||
store: store,
|
||||
taskDistributor: taskDistributor,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *userService) CreateUser(ctx context.Context, params RegisterUserRequest) (*RegisterUserResponse, error) {
|
||||
// Hash the password
|
||||
hashedPassword, err := security.HashPassword(params.Password)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to hash password: %w", err)
|
||||
}
|
||||
|
||||
// Prepare transaction parameters
|
||||
arg := db.CreateUserTxParams{
|
||||
CreateUserParams: db.CreateUserParams{
|
||||
Username: params.Username,
|
||||
FullName: params.FullName,
|
||||
Email: params.Email,
|
||||
HashedPassword: hashedPassword,
|
||||
},
|
||||
AfterCreate: func(user db.User) error {
|
||||
opts := []asynq.Option{
|
||||
asynq.MaxRetry(10),
|
||||
asynq.ProcessIn(10 * time.Second),
|
||||
asynq.Queue(worker.CriticalQueue),
|
||||
}
|
||||
taskPayload := &worker.SendVerifyEmailPayload{
|
||||
Username: user.Username,
|
||||
}
|
||||
return s.taskDistributor.DestributeTaskSendVerifyEmail(ctx, taskPayload, opts...)
|
||||
},
|
||||
}
|
||||
|
||||
// Execute transaction
|
||||
txResult, err := s.store.CreateUserTx(ctx, arg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create user: %w", err)
|
||||
}
|
||||
|
||||
return &RegisterUserResponse{User: txResult.User}, nil
|
||||
}
|
||||
|
||||
func (s *userService) GetUser(ctx context.Context, username string) (*db.User, error) {
|
||||
user, err := s.store.GetUser(ctx, username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (s *userService) UpdateUser(ctx context.Context, params UserUpdateRequest) (*db.User, error) {
|
||||
arg := db.UpdateUserParams{
|
||||
Username: params.Username,
|
||||
FullName: pgtype.Text{
|
||||
String: *params.FullName,
|
||||
Valid: params.FullName != nil,
|
||||
},
|
||||
Email: pgtype.Text{
|
||||
String: *params.Email,
|
||||
Valid: params.Email != nil,
|
||||
},
|
||||
}
|
||||
|
||||
user, err := s.store.UpdateUser(ctx, arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (s *userService) UpdatePassword(ctx context.Context, params PasswordUpdateRequest) (*db.User, error) {
|
||||
user, err := s.store.GetUser(ctx, params.Username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = security.CheckPassword(params.OldPassword, user.HashedPassword)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("old password does not match: %w", err)
|
||||
}
|
||||
|
||||
newHashedPassword, err := security.HashPassword(params.NewPassword)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to hash new password: %w", err)
|
||||
}
|
||||
|
||||
updUser, err := s.store.UpdateUser(ctx, db.UpdateUserParams{
|
||||
Username: params.Username,
|
||||
HashedPassword: pgtype.Text{
|
||||
String: newHashedPassword,
|
||||
Valid: true,
|
||||
},
|
||||
PasswordChangedAt: pgtype.Timestamptz{
|
||||
Time: time.Now(),
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &updUser, nil
|
||||
}
|
||||
|
||||
func (s *userService) VerifyEmail(ctx context.Context, params EmailVerificationRequest) (*EmailVerificationResponse, error) {
|
||||
txRes, err := s.store.VerifyEmailTx(ctx, db.VerifyEmailTxParams{
|
||||
EmailID: params.EmailID,
|
||||
SecretCode: params.SecretCode,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &EmailVerificationResponse{User: txRes.User}, nil
|
||||
}
|
||||
Reference in new issue
Block a user