82 lines
2.2 KiB
Go
82 lines
2.2 KiB
Go
package useCases
|
|
|
|
import (
|
|
"RenewCMS/internal/domain/hash"
|
|
"RenewCMS/internal/domain/mail"
|
|
"RenewCMS/internal/domain/user"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
const (
|
|
verifyNewEmailTemplateName = "verify-new-email"
|
|
emailChangeNoticeTemplateName = "email-change-notice"
|
|
)
|
|
|
|
type MailVerifyNewEmailData struct {
|
|
Host string
|
|
Username string
|
|
VerificationCode string
|
|
}
|
|
|
|
type MailEmailChangeNoticeData struct {
|
|
Host string
|
|
Username string
|
|
NewEmail string
|
|
}
|
|
|
|
type emailChangeIssuer struct {
|
|
userRepository user.Repository
|
|
hasher hash.Hasher
|
|
mailRepository mail.Repository
|
|
dispatcher mail.Dispatcher
|
|
publicURL string
|
|
now func() time.Time
|
|
}
|
|
|
|
func (i emailChangeIssuer) issue(account user.User, pendingEmail string) (user.User, error) {
|
|
rawCode := uuid.NewString()
|
|
hashedCode, err := i.hasher.Hash(rawCode)
|
|
if err != nil {
|
|
return user.User{}, err
|
|
}
|
|
updated, err := i.userRepository.SetPendingEmailChange(account.ID, pendingEmail, hashedCode, i.now().Add(user.EmailChangeLifetime))
|
|
if err != nil {
|
|
return user.User{}, err
|
|
}
|
|
i.dispatcher.Dispatch(func() { i.sendVerification(account, pendingEmail, rawCode) })
|
|
return updated, nil
|
|
}
|
|
|
|
func (i emailChangeIssuer) sendVerification(account user.User, pendingEmail string, rawCode string) {
|
|
taken, err := i.userRepository.IsEmailInUse(pendingEmail, account.ID)
|
|
if err != nil {
|
|
log.Println("error when checking whether the new email address is in use:", err)
|
|
return
|
|
}
|
|
if taken {
|
|
return
|
|
}
|
|
if err := i.mailRepository.Send(pendingEmail, verifyNewEmailTemplateName, MailVerifyNewEmailData{
|
|
Host: i.publicURL,
|
|
Username: account.Username,
|
|
VerificationCode: rawCode,
|
|
}); err != nil {
|
|
log.Println("error when Send-ing the new email verification mail:", err)
|
|
}
|
|
}
|
|
|
|
func (i emailChangeIssuer) sendNotice(account user.User, pendingEmail string) {
|
|
i.dispatcher.Dispatch(func() {
|
|
if err := i.mailRepository.Send(account.Email, emailChangeNoticeTemplateName, MailEmailChangeNoticeData{
|
|
Host: i.publicURL,
|
|
Username: account.Username,
|
|
NewEmail: pendingEmail,
|
|
}); err != nil {
|
|
log.Println("error when Send-ing the email change notice mail:", err)
|
|
}
|
|
})
|
|
}
|