(r *http.Request, tx *storage.Connection, u *models.User, params sendEmailParams)
| 757 | } |
| 758 | |
| 759 | func (a *API) sendEmail(r *http.Request, tx *storage.Connection, u *models.User, params sendEmailParams) error { |
| 760 | ctx := r.Context() |
| 761 | config := a.config |
| 762 | referrerURL := utilities.GetReferrer(r, config) |
| 763 | externalURL := getExternalHost(ctx) |
| 764 | otp := params.otp |
| 765 | |
| 766 | if params.emailActionType != mail.EmailChangeVerification { |
| 767 | if u.GetEmail() != "" && !a.checkEmailAddressAuthorization(u.GetEmail()) { |
| 768 | return apierrors.NewBadRequestError(apierrors.ErrorCodeEmailAddressNotAuthorized, "Email address %q cannot be used as it is not authorized", u.GetEmail()) |
| 769 | } |
| 770 | } else { |
| 771 | // first check that the user can update their address to the |
| 772 | // new one in u.EmailChange |
| 773 | if u.EmailChange != "" && !a.checkEmailAddressAuthorization(u.EmailChange) { |
| 774 | return apierrors.NewBadRequestError(apierrors.ErrorCodeEmailAddressNotAuthorized, "Email address %q cannot be used as it is not authorized", u.EmailChange) |
| 775 | } |
| 776 | |
| 777 | // if secure email change is enabled, check that the user |
| 778 | // account (which could have been created before the authorized |
| 779 | // address authorization restriction was enabled) can even |
| 780 | // receive the confirmation message to the existing address |
| 781 | if config.Mailer.SecureEmailChangeEnabled && u.GetEmail() != "" && !a.checkEmailAddressAuthorization(u.GetEmail()) { |
| 782 | return apierrors.NewBadRequestError(apierrors.ErrorCodeEmailAddressNotAuthorized, "Email address %q cannot be used as it is not authorized", u.GetEmail()) |
| 783 | } |
| 784 | } |
| 785 | |
| 786 | // if the number of events is set to zero, we immediately apply rate limits. |
| 787 | if config.RateLimitEmailSent.Events == 0 { |
| 788 | emailRateLimitCounter.Add( |
| 789 | ctx, |
| 790 | 1, |
| 791 | metric.WithAttributeSet(attribute.NewSet(attribute.String("path", r.URL.Path))), |
| 792 | ) |
| 793 | return EmailRateLimitExceeded |
| 794 | } |
| 795 | |
| 796 | // TODO(km): Deprecate this behaviour - rate limits should still be applied to autoconfirm |
| 797 | if !config.Mailer.Autoconfirm { |
| 798 | // apply rate limiting before the email is sent out |
| 799 | if ok := a.limiterOpts.Email.Allow(); !ok { |
| 800 | emailRateLimitCounter.Add( |
| 801 | ctx, |
| 802 | 1, |
| 803 | metric.WithAttributeSet(attribute.NewSet(attribute.String("path", r.URL.Path))), |
| 804 | ) |
| 805 | return EmailRateLimitExceeded |
| 806 | } |
| 807 | } |
| 808 | |
| 809 | if config.Hook.SendEmail.Enabled { |
| 810 | // When secure email change is disabled, we place the token for the new email on emailData.Token |
| 811 | if params.emailActionType == mail.EmailChangeVerification && !config.Mailer.SecureEmailChangeEnabled && u.GetEmail() != "" { |
| 812 | |
| 813 | // BUG(cstockton): This introduced a bug which mismatched the token |
| 814 | // and hash fields, such that: |
| 815 | // |
| 816 | // EmailData.TokenHashNew = Hash(CurEmail, EmailData.Token) |
no test coverage detected