(r *http.Request, tx *storage.Connection, u *models.User, flowType models.FlowType)
| 316 | } |
| 317 | |
| 318 | func (a *API) sendConfirmation(r *http.Request, tx *storage.Connection, u *models.User, flowType models.FlowType) error { |
| 319 | var err error |
| 320 | |
| 321 | config := a.config |
| 322 | maxFrequency := config.SMTP.MaxFrequency |
| 323 | otpLength := config.Mailer.OtpLength |
| 324 | |
| 325 | if err = validateSentWithinFrequencyLimit(u.ConfirmationSentAt, maxFrequency); err != nil { |
| 326 | return err |
| 327 | } |
| 328 | oldToken := u.ConfirmationToken |
| 329 | otp := crypto.GenerateOtp(otpLength) |
| 330 | |
| 331 | token := crypto.GenerateTokenHash(u.GetEmail(), otp) |
| 332 | u.ConfirmationToken = addFlowPrefixToToken(token, flowType) |
| 333 | now := time.Now() |
| 334 | if err = a.sendEmail(r, tx, u, sendEmailParams{ |
| 335 | emailActionType: mail.SignupVerification, |
| 336 | otp: otp, |
| 337 | tokenHashWithPrefix: u.ConfirmationToken, |
| 338 | }); err != nil { |
| 339 | u.ConfirmationToken = oldToken |
| 340 | if errors.Is(err, EmailRateLimitExceeded) { |
| 341 | return apierrors.NewTooManyRequestsError(apierrors.ErrorCodeOverEmailSendRateLimit, "%s", EmailRateLimitExceeded.Error()) |
| 342 | } else if herr, ok := err.(*HTTPError); ok { |
| 343 | return herr |
| 344 | } |
| 345 | return apierrors.NewInternalServerError("Error sending confirmation email").WithInternalError(err) |
| 346 | } |
| 347 | u.ConfirmationSentAt = &now |
| 348 | if err := tx.UpdateOnly(u, "confirmation_token", "confirmation_sent_at"); err != nil { |
| 349 | return apierrors.NewInternalServerError("Error sending confirmation email").WithInternalError(errors.Wrap(err, "Database error updating user for confirmation")) |
| 350 | } |
| 351 | |
| 352 | if err := models.CreateOneTimeToken(tx, u.ID, u.GetEmail(), u.ConfirmationToken, models.ConfirmationToken); err != nil { |
| 353 | return apierrors.NewInternalServerError("Error sending confirmation email").WithInternalError(errors.Wrap(err, "Database error creating confirmation token")) |
| 354 | } |
| 355 | |
| 356 | return nil |
| 357 | } |
| 358 | |
| 359 | func (a *API) sendInvite(r *http.Request, tx *storage.Connection, u *models.User) error { |
| 360 | config := a.config |
no test coverage detected