package accountapiimp import ( "context" "encoding/json" "net/http" "github.com/tech/sendico/pkg/api/http/response" "github.com/tech/sendico/pkg/db/account" an "github.com/tech/sendico/pkg/messaging/notifications/account" "github.com/tech/sendico/pkg/model" "github.com/tech/sendico/pkg/mutil/mzap" "github.com/tech/sendico/server/interface/api/sresponse" "go.uber.org/zap" ) func (a *AccountAPI) attemptDecodeAccount(r *http.Request) (*model.Account, error) { var u model.Account return &u, json.NewDecoder(r.Body).Decode(&u) } func (a *AccountAPI) reportUnauthorized(hint string) http.HandlerFunc { return response.Unauthorized(a.logger, a.Name(), hint) } func (a *AccountAPI) reportDuplicateEmail() http.HandlerFunc { return response.Forbidden(a.logger, a.Name(), "duplicate_email", "email has already been registered") } func (a *AccountAPI) reportEmailMissing() http.HandlerFunc { return response.BadRequest(a.logger, a.Name(), "email_missing", "email is required") } func (a *AccountAPI) sendPasswordResetEmail(account *model.Account, resetToken string) error { if err := a.producer.SendMessage(an.PasswordResetRequested(a.Name(), *account.GetID(), resetToken)); err != nil { a.logger.Warn("Failed to send password reset notification", zap.Error(err)) return err } return nil } func (a *AccountAPI) getProfile(_ *http.Request, u *model.Account, token *sresponse.TokenData) http.HandlerFunc { return sresponse.Account(a.logger, u, token) } func (a *AccountAPI) sendWelcomeEmail(account *model.Account, token string) error { if err := a.producer.SendMessage(an.AccountCreated(a.Name(), *account.GetID(), token)); err != nil { a.logger.Warn("Failed to send account creation notification", zap.Error(err)) return err } return nil } func (a *AccountAPI) sendVerificationMail(r *http.Request, paramGetter func(ctx context.Context, db account.DB, user *model.Account) (*model.Account, error)) http.HandlerFunc { // Validate user input u, err := a.attemptDecodeAccount(r) if err != nil { a.logger.Warn("Failed to decide profile update", zap.Error(err)) return response.Internal(a.logger, a.Name(), err) } ctx := r.Context() accnt, err := paramGetter(ctx, a.db, u) if err != nil || accnt == nil { a.logger.Warn("Failed to ger user from db with", zap.Error(err), mzap.StorableRef(u)) return response.Internal(a.logger, a.Name(), err) } token, err := a.accService.VerifyAccount(ctx, accnt) if err != nil { a.logger.Warn("Failed to create verification token for account", zap.Error(err), mzap.StorableRef(accnt)) return response.Internal(a.logger, a.Name(), err) } // Send welcome email if err = a.sendWelcomeEmail(accnt, token); err != nil { a.logger.Warn("Failed to send verification email", zap.Error(err), mzap.StorableRef(accnt), zap.String("email", accnt.Login)) return response.Internal(a.logger, a.Name(), err) } return response.Success(a.logger) } func getID(ctx context.Context, db account.DB, u *model.Account) (*model.Account, error) { var res model.Account return &res, db.Get(ctx, *u.GetID(), &res) } func getEmail(ctx context.Context, db account.DB, u *model.Account) (*model.Account, error) { return db.GetByEmail(ctx, u.Login) } func (a *AccountAPI) reportNoEmailRegistered() http.HandlerFunc { return response.BadRequest(a.logger, a.Name(), "email_not_registered", "no account registered with this email") }