Contact Form
A generic form which is attached to email addresses found on boston.gov, and handles sending emails to those addresses.
Last updated
Was this helpful?
A generic form which is attached to email addresses found on boston.gov, and handles sending emails to those addresses.
Last updated
Was this helpful?
This app uses the bos_email
provided services as .
A contact us form template is maintained (within script tags) in bos_theme/templates/snippets/contactFormTemplate.html.twig
and is included on every boston.gov (Drupal) page.
The patterns library contact form javascript function start()
(in scripts/components/contact.js
) is executed when a boston.gov (Drupal) page loads.
The start()
function scans the completed page looking for email addresses anywhere in the html being served. Essentially, it:
- replaces the default mailto
directive for each email address with a click event listener which will trigger the handleEmailClick()
function, and
- attaches a click event listener to the forms' submit button and calls the handleFormSubmit()
function when the user clicks the submit button on the contact form.
TODO: The handleEmailClick()
function is called once when the page has finished loading.
It should be extended to also run when ajax events return data to the page (since email addresses could be served by XHR/AJAX as well as traditional document events)..
@see
When an email address is clicked on the page, handleEmailClick()
- copies the template form from the script tags,
- inserts the correct email recipient to a hidden field,
- inserts all this onto the page and displays the contact us form, and
- in the background makes an ajax request to /rest/email_token/create,
generating and saving a unique "session" token in the form.
When the submit button is clicked, handleFormSubmit()
validates the form, and then submits, along with an authorization token to /rest/email_session/contactform
.
This requirement could be obselete, and a requirement from earler versions of the form. Can consider removing this "feature" and reverting to having the sender be the email address provided by constituent. That way the cob employee/recipient can simply reply to the email.
Emails are sent from an email address that is generated for each email sent. The format of the email address is:
{random_string}@contactform.boston.gov
We don't send the email from the original sender's email address as that could be a vector for an email spoofing attack.
The reply_to header of the email is set to the constituents email first and the unique address of the contact form second. When someone replies to the email the to address of the email is set to the constituents email first and the unique address second. This delivers two copies of the email. One goes directly to the constituent, and one to the contact form API. We log the response time using the copy that gets sent to the contact form API. Once the reply email is delivered to the constituent, further replies will be direct between the constituent and city.
The contact us email which is sent from postMark to the cob recipient is a plain text email.
The PostmarkAPI is capable of generating HTML emails. A nicer experience for cob staff would be to receive an html email.
As well as the tokens etc, we could consider introducing an IP lock for say 60sec after a contact form submission is made (the timer should be managed on the server side, inside the endpoint). It should not affect genuine users but would minimize the impact (and success) of flood attacks and relay exploits on the endpoint. If there were a rapid second submission from the same IPAddress, we would flash a warning back to the user to try again after 60 seconds.
At the moment, there is no confirmation of a successful submission other than the on-screen notification. We have the submitters' email address, so we could send an email confirming the submission (see next enhancement).
There is little in the way of validation of the email the submitter provides as a contact for responses.
The JavaScript validation process does checks that a "visually" valid email pattern is entered, (i.e. it is an email pattern string) but does not validate the email address exists.
If we send email confirmations, then we could use that process to determine if the email address is active and does not have temporary errors (mailbox full etc). Since we are using AJAX it would be simple to end the confirmation email, wait a period of time (say 10sec) and then query postMark to see if the email was delivered. If it was then return success, if not then flag to the submitter on the form. This would not be 100% effective because some errors take time to be reported, and we cannot wait too long during validation. The other two approaches above should still be implemented to try to filter out malicious actions, and to detect innocent errors before consuming email server resources.
(needs updating)
2022 this ticket () added a second email address box to try to prevent typos in the email address. While it helped a lot, it is not 100% effective and some emails from innocent errors and malicious actors (e.g. spammers) still slip through.
2023 provided some modules which can check for DNS validity, disposable emails and also email blacklists. This would further help reduce invalid sender email addresses being provided.