roadmap icon indicating copy to clipboard operation
roadmap copied to clipboard

Two Emails Sometimes Sent to `ContactUs.mailer_to` When Submitting Form on `/contact-us` Page

Open aaronskiba opened this issue 5 months ago • 0 comments

Description

The /contact-us page features a "contact us" form. After clicking "Submit", an email should be delivered to the value assigned to ContactUs.mailer_to.

However, there are scenarios where a single submission of the "contact us" form results in two identical emails being sent to ContactUs.mailer_to.

Technical Details

The following is the ContactUs#create action from the ContactsController (https://github.com/DMPRoadmap/roadmap/blob/main/app/controllers/contact_us/contacts_controller.rb):


# frozen_string_literal: true

module ContactUs
  # Controller for the Contact Us gem
  class ContactsController < ApplicationController
    # rubocop:disable Metrics/AbcSize
    # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
    def create
      @contact = ContactUs::Contact.new(params[:contact_us_contact])

      if !user_signed_in? && Rails.configuration.x.recaptcha.enabled &&
         !(verify_recaptcha(model: @contact) && @contact.save)
        flash[:alert] = _('Captcha verification failed, please retry.')
        render_new_page and return
      end
      if @contact.save
        redirect_to(ContactUs.success_redirect || '/',
                    notice: _('Contact email was successfully sent.'))
      else
        flash[:alert] = _('Unable to submit your request')
        render_new_page
      end
    end
    # rubocop:enable Metrics/AbcSize
    # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

The execution of @contact.save results in the delivery of the contact us email. We can see two references to @contact.save in the above code snippet. Both of the @contact.save references will be executed in the following scenario:

Example of Two Emails Being Sent

      if !user_signed_in? && Rails.configuration.x.recaptcha.enabled &&
         !(verify_recaptcha(model: @contact) && @contact.save)

Here, if the user is signed out, and recaptcha is enabled, and the recaptcha verification is successful, then @contact.save is executed and one email is sent.

However, the if condition will be evaluated to false and the controller action will next immediately execute the following:

 if @contact.save

This will result in the delivery of a second email to ContactUs.mailer_to.

aaronskiba avatar Jul 17 '25 16:07 aaronskiba