package useCases import ( "RenewCMS/internal/domain/audit" "RenewCMS/internal/domain/hash" "RenewCMS/internal/domain/invite" "RenewCMS/internal/domain/mail" "RenewCMS/internal/domain/user" "context" "errors" "time" ) type RenewInviteUseCase struct { userRepository user.Repository inviteRepository invite.Repository hasher hash.Hasher mailer inviteMailer recorder audit.Recorder } type RenewInviteCommand struct { ID uint32 RenewedBy uint32 } func NewRenewInviteUseCase(userRepository user.Repository, inviteRepository invite.Repository, hasher hash.Hasher, mailRepository mail.Repository, publicURL string, recorder audit.Recorder) *RenewInviteUseCase { return &RenewInviteUseCase{userRepository, inviteRepository, hasher, inviteMailer{mailRepository, publicURL}, recorder} } func (u *RenewInviteUseCase) RenewInvite(ctx context.Context, command RenewInviteCommand) (invite.Invite, error) { event := audit.NewEvent(audit.ActionInviteRenew, audit.CategoryUsers) renewed, err := u.renew(command) if err != nil { recordFailure(ctx, u.recorder, event, err) return invite.Invite{}, err } event.Target = inviteTarget(renewed) u.recorder.Record(ctx, event) return renewed, nil } func (u *RenewInviteUseCase) renew(command RenewInviteCommand) (invite.Invite, error) { now := time.Now() renewer, err := u.userRepository.Get(command.RenewedBy) if err != nil { return invite.Invite{}, err } previous, err := findManageableInvite(u.inviteRepository, command.ID) if err != nil { return invite.Invite{}, err } rawCode, hashedCode, err := newInviteCode(u.hasher) if err != nil { return invite.Invite{}, err } renewed, err := u.inviteRepository.Renew(previous.ID, hashedCode, now.Add(invite.Lifetime), now) if err != nil { return invite.Invite{}, err } if sendErr := u.mailer.send(renewed.Email, rawCode, renewer); sendErr != nil { if _, restoreErr := u.inviteRepository.Renew(previous.ID, previous.HashedCode, previous.ExpiresAt, previous.CreatedAt); restoreErr != nil { return invite.Invite{}, errors.Join(sendErr, restoreErr) } return invite.Invite{}, sendErr } return renewed, nil }