2025-04-29 06:03:47 +02:00
|
|
|
package domain
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2025-04-30 09:30:48 +02:00
|
|
|
"time"
|
2025-04-29 06:03:47 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type EmailVerifiedCommand struct {
|
|
|
|
UserID string `json:"userId"`
|
|
|
|
Email *Email `json:"email"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewEmailVerifiedCommand(userID string, isVerified bool) *EmailVerifiedCommand {
|
|
|
|
return &EmailVerifiedCommand{
|
|
|
|
UserID: userID,
|
|
|
|
Email: &Email{
|
2025-05-06 07:18:11 +02:00
|
|
|
VerifiedAt: time.Time{},
|
2025-04-29 06:03:47 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ Commander = (*EmailVerifiedCommand)(nil)
|
|
|
|
_ SetEmailOpt = (*EmailVerifiedCommand)(nil)
|
|
|
|
)
|
|
|
|
|
|
|
|
// Execute implements [Commander]
|
|
|
|
func (cmd *EmailVerifiedCommand) Execute(ctx context.Context, opts *CommandOpts) error {
|
2025-04-30 09:30:48 +02:00
|
|
|
repo := userRepo(opts.DB).Human()
|
|
|
|
return repo.Update(ctx, repo.IDCondition(cmd.UserID), repo.SetEmailVerifiedAt(time.Time{}))
|
2025-04-29 06:03:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// applyOnSetEmail implements [SetEmailOpt]
|
|
|
|
func (cmd *EmailVerifiedCommand) applyOnSetEmail(setEmailCmd *SetEmailCommand) {
|
|
|
|
cmd.UserID = setEmailCmd.UserID
|
|
|
|
cmd.Email.Address = setEmailCmd.Email
|
|
|
|
setEmailCmd.verification = cmd
|
|
|
|
}
|
|
|
|
|
|
|
|
type SendCodeCommand struct {
|
|
|
|
UserID string `json:"userId"`
|
|
|
|
Email string `json:"email"`
|
|
|
|
URLTemplate *string `json:"urlTemplate"`
|
|
|
|
generator *generateCodeCommand
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ Commander = (*SendCodeCommand)(nil)
|
|
|
|
_ SetEmailOpt = (*SendCodeCommand)(nil)
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewSendCodeCommand(userID string, urlTemplate *string) *SendCodeCommand {
|
|
|
|
return &SendCodeCommand{
|
|
|
|
UserID: userID,
|
|
|
|
generator: &generateCodeCommand{},
|
|
|
|
URLTemplate: urlTemplate,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Execute implements [Commander]
|
|
|
|
func (cmd *SendCodeCommand) Execute(ctx context.Context, opts *CommandOpts) error {
|
|
|
|
if err := cmd.ensureEmail(ctx, opts); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := cmd.ensureURL(ctx, opts); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := opts.Invoker.Invoke(ctx, cmd.generator, opts); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// TODO: queue notification
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cmd *SendCodeCommand) ensureEmail(ctx context.Context, opts *CommandOpts) error {
|
|
|
|
if cmd.Email != "" {
|
|
|
|
return nil
|
|
|
|
}
|
2025-04-30 09:30:48 +02:00
|
|
|
repo := userRepo(opts.DB).Human()
|
|
|
|
email, err := repo.GetEmail(ctx, repo.IDCondition(cmd.UserID))
|
|
|
|
if err != nil || !email.VerifiedAt.IsZero() {
|
2025-04-29 06:03:47 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
cmd.Email = email.Address
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cmd *SendCodeCommand) ensureURL(ctx context.Context, opts *CommandOpts) error {
|
|
|
|
if cmd.URLTemplate != nil && *cmd.URLTemplate != "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
_, _ = ctx, opts
|
|
|
|
// TODO: load default template
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// applyOnSetEmail implements [SetEmailOpt]
|
|
|
|
func (cmd *SendCodeCommand) applyOnSetEmail(setEmailCmd *SetEmailCommand) {
|
|
|
|
cmd.UserID = setEmailCmd.UserID
|
|
|
|
cmd.Email = setEmailCmd.Email
|
|
|
|
setEmailCmd.verification = cmd
|
|
|
|
}
|
|
|
|
|
|
|
|
type ReturnCodeCommand struct {
|
|
|
|
UserID string `json:"userId"`
|
|
|
|
Email string `json:"email"`
|
|
|
|
Code string `json:"code"`
|
|
|
|
generator *generateCodeCommand
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ Commander = (*ReturnCodeCommand)(nil)
|
|
|
|
_ SetEmailOpt = (*ReturnCodeCommand)(nil)
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewReturnCodeCommand(userID string) *ReturnCodeCommand {
|
|
|
|
return &ReturnCodeCommand{
|
|
|
|
UserID: userID,
|
|
|
|
generator: &generateCodeCommand{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Execute implements [Commander]
|
|
|
|
func (cmd *ReturnCodeCommand) Execute(ctx context.Context, opts *CommandOpts) error {
|
|
|
|
if err := cmd.ensureEmail(ctx, opts); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := opts.Invoker.Invoke(ctx, cmd.generator, opts); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
cmd.Code = cmd.generator.code
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cmd *ReturnCodeCommand) ensureEmail(ctx context.Context, opts *CommandOpts) error {
|
|
|
|
if cmd.Email != "" {
|
|
|
|
return nil
|
|
|
|
}
|
2025-04-30 09:30:48 +02:00
|
|
|
repo := userRepo(opts.DB).Human()
|
|
|
|
email, err := repo.GetEmail(ctx, repo.IDCondition(cmd.UserID))
|
|
|
|
if err != nil || !email.VerifiedAt.IsZero() {
|
2025-04-29 06:03:47 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
cmd.Email = email.Address
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// applyOnSetEmail implements [SetEmailOpt]
|
|
|
|
func (cmd *ReturnCodeCommand) applyOnSetEmail(setEmailCmd *SetEmailCommand) {
|
|
|
|
cmd.UserID = setEmailCmd.UserID
|
|
|
|
cmd.Email = setEmailCmd.Email
|
|
|
|
setEmailCmd.verification = cmd
|
|
|
|
}
|