add forget password
This commit is contained in:
@@ -2,7 +2,10 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"furtuna-be/config"
|
||||
"furtuna-be/internal/common/mycontext"
|
||||
"furtuna-be/internal/entity"
|
||||
"furtuna-be/internal/utils"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
@@ -14,12 +17,23 @@ import (
|
||||
type AuthServiceImpl struct {
|
||||
authRepo repository.Auth
|
||||
crypto repository.Crypto
|
||||
user repository.User
|
||||
emailSvc repository.EmailService
|
||||
emailCfg config.Email
|
||||
trxRepo repository.TransactionManager
|
||||
}
|
||||
|
||||
func New(authRepo repository.Auth, crypto repository.Crypto) *AuthServiceImpl {
|
||||
func New(authRepo repository.Auth,
|
||||
crypto repository.Crypto, user repository.User, emailSvc repository.EmailService,
|
||||
emailCfg config.Email, trxRepo repository.TransactionManager,
|
||||
) *AuthServiceImpl {
|
||||
return &AuthServiceImpl{
|
||||
authRepo: authRepo,
|
||||
crypto: crypto,
|
||||
user: user,
|
||||
emailSvc: emailSvc,
|
||||
emailCfg: emailCfg,
|
||||
trxRepo: trxRepo,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,3 +60,115 @@ func (u *AuthServiceImpl) AuthenticateUser(ctx context.Context, email, password
|
||||
|
||||
return user.ToUserAuthenticate(signedToken), nil
|
||||
}
|
||||
|
||||
func (u *AuthServiceImpl) SendPasswordResetLink(ctx context.Context, email string) error {
|
||||
// Check if the user exists
|
||||
user, err := u.authRepo.CheckExistsUserAccount(ctx, email)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when getting user", zap.Error(err))
|
||||
return errors.ErrorInternalServer
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
return errors.ErrorUserIsNotFound
|
||||
}
|
||||
|
||||
// Begin a transaction
|
||||
trx, err := u.trxRepo.Begin(ctx)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when beginning transaction", zap.Error(err))
|
||||
return errors.ErrorInternalServer
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
u.trxRepo.Rollback(trx)
|
||||
logger.ContextLogger(ctx).Error("panic recovered in SendPasswordResetLink", zap.Any("recover", r))
|
||||
err = errors.ErrorInternalServer
|
||||
}
|
||||
}()
|
||||
|
||||
// Generate a new password
|
||||
generatedPassword := utils.GenerateRandomString(10)
|
||||
hashPassword, err := user.ToUser().HashedPassword(generatedPassword)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when generating hashed password", zap.Error(err))
|
||||
u.trxRepo.Rollback(trx)
|
||||
return errors.ErrorInternalServer
|
||||
}
|
||||
|
||||
// Update the user's password in the database
|
||||
if err := u.authRepo.UpdatePassword(ctx, trx, hashPassword, user.ID, true); err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when updating user password", zap.Error(err))
|
||||
u.trxRepo.Rollback(trx)
|
||||
return errors.ErrorInternalServer
|
||||
}
|
||||
|
||||
// If a custom receiver is specified, override the email
|
||||
if u.emailCfg.CustomReceiver != "" {
|
||||
email = u.emailCfg.CustomReceiver
|
||||
}
|
||||
|
||||
// Prepare the email notification parameters
|
||||
renewPasswordRequest := entity.SendEmailNotificationParam{
|
||||
Recipient: email,
|
||||
Subject: u.emailCfg.ResetPassword.Subject,
|
||||
TemplateName: u.emailCfg.ResetPassword.TemplateName,
|
||||
TemplatePath: u.emailCfg.ResetPassword.TemplatePath,
|
||||
Data: map[string]interface{}{
|
||||
"Name": user.Name,
|
||||
"OpeningWord": u.emailCfg.ResetPassword.OpeningWord,
|
||||
"Password": generatedPassword,
|
||||
"ClosingWord": u.emailCfg.ResetPassword.ClosingWord,
|
||||
"Note": u.emailCfg.ResetPassword.Notes,
|
||||
"Link": u.emailCfg.ResetPassword.Link,
|
||||
},
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
u.trxRepo.Rollback(trx)
|
||||
logger.ContextLogger(ctx).Error("panic recovered in SendPasswordResetLink", zap.Any("recover", r))
|
||||
err = errors.ErrorInternalServer
|
||||
}
|
||||
}()
|
||||
|
||||
// Send the email notification
|
||||
err = u.emailSvc.SendEmailTransactional(ctx, renewPasswordRequest)
|
||||
if err != nil {
|
||||
u.trxRepo.Rollback(trx)
|
||||
logger.ContextLogger(ctx).Error("error when sending password reset email", zap.Error(err))
|
||||
return errors.ErrorInternalServer
|
||||
}
|
||||
|
||||
trx.Commit()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *AuthServiceImpl) ResetPassword(ctx mycontext.Context, oldPassword, newPassword string) error {
|
||||
user, err := u.authRepo.CheckExistsUserAccountByID(ctx, ctx.RequestedBy())
|
||||
if err != nil {
|
||||
return errors.ErrorInvalidRequest
|
||||
}
|
||||
|
||||
if ok := u.crypto.CompareHashAndPassword(user.Password, oldPassword); !ok {
|
||||
return errors.ErrorUserInvalidLogin
|
||||
}
|
||||
|
||||
password, err := user.ToUser().HashedPassword(newPassword)
|
||||
if err != nil {
|
||||
return errors.ErrorInvalidRequest
|
||||
}
|
||||
|
||||
trx, _ := u.trxRepo.Begin(ctx)
|
||||
|
||||
err = u.authRepo.UpdatePassword(ctx, trx, password, user.ID, false)
|
||||
if err != nil {
|
||||
return errors.ErrorInternalServer
|
||||
}
|
||||
|
||||
trx.Commit()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ type ServiceManagerImpl struct {
|
||||
|
||||
func NewServiceManagerImpl(cfg *config.Config, repo *repository.RepoManagerImpl) *ServiceManagerImpl {
|
||||
return &ServiceManagerImpl{
|
||||
AuthSvc: auth.New(repo.Auth, repo.Crypto),
|
||||
AuthSvc: auth.New(repo.Auth, repo.Crypto, repo.User, repo.EmailService, cfg.Email, repo.Trx),
|
||||
EventSvc: event.NewEventService(repo.Event),
|
||||
UserSvc: users.NewUserService(repo.User, repo.Branch),
|
||||
BranchSvc: branch.NewBranchService(repo.Branch),
|
||||
@@ -52,6 +52,8 @@ func NewServiceManagerImpl(cfg *config.Config, repo *repository.RepoManagerImpl)
|
||||
|
||||
type Auth interface {
|
||||
AuthenticateUser(ctx context.Context, email, password string) (*entity.AuthenticateUser, error)
|
||||
SendPasswordResetLink(ctx context.Context, email string) error
|
||||
ResetPassword(ctx mycontext.Context, oldPassword, newPassword string) error
|
||||
}
|
||||
|
||||
type Event interface {
|
||||
|
||||
Reference in New Issue
Block a user