(r *http.Request, tx *storage.Connection, u *models.User)
| 357 | } |
| 358 | |
| 359 | func (a *API) sendInvite(r *http.Request, tx *storage.Connection, u *models.User) error { |
| 360 | config := a.config |
| 361 | otpLength := config.Mailer.OtpLength |
| 362 | var err error |
| 363 | oldToken := u.ConfirmationToken |
| 364 | otp := crypto.GenerateOtp(otpLength) |
| 365 | |
| 366 | u.ConfirmationToken = crypto.GenerateTokenHash(u.GetEmail(), otp) |
| 367 | now := time.Now() |
| 368 | err = a.sendEmail(r, tx, u, sendEmailParams{ |
| 369 | emailActionType: mail.InviteVerification, |
| 370 | otp: otp, |
| 371 | tokenHashWithPrefix: u.ConfirmationToken, |
| 372 | }) |
| 373 | if err != nil { |
| 374 | u.ConfirmationToken = oldToken |
| 375 | if errors.Is(err, EmailRateLimitExceeded) { |
| 376 | return apierrors.NewTooManyRequestsError(apierrors.ErrorCodeOverEmailSendRateLimit, "%s", EmailRateLimitExceeded.Error()) |
| 377 | } else if herr, ok := err.(*HTTPError); ok { |
| 378 | return herr |
| 379 | } |
| 380 | return apierrors.NewInternalServerError("Error sending invite email").WithInternalError(err) |
| 381 | } |
| 382 | u.InvitedAt = &now |
| 383 | u.ConfirmationSentAt = &now |
| 384 | err = tx.UpdateOnly(u, "confirmation_token", "confirmation_sent_at", "invited_at") |
| 385 | if err != nil { |
| 386 | return apierrors.NewInternalServerError("Error inviting user").WithInternalError(errors.Wrap(err, "Database error updating user for invite")) |
| 387 | } |
| 388 | |
| 389 | err = models.CreateOneTimeToken(tx, u.ID, u.GetEmail(), u.ConfirmationToken, models.ConfirmationToken) |
| 390 | if err != nil { |
| 391 | return apierrors.NewInternalServerError("Error inviting user").WithInternalError(errors.Wrap(err, "Database error creating confirmation token for invite")) |
| 392 | } |
| 393 | |
| 394 | return nil |
| 395 | } |
| 396 | |
| 397 | func (a *API) sendPasswordRecovery(r *http.Request, tx *storage.Connection, u *models.User, flowType models.FlowType) error { |
| 398 | config := a.config |
no test coverage detected