The latest release of holdmail brings several improvements:
- Support for attachments
- Multilingual support
- A new UI (We're now using Vue.js as the UI framework)
- Direct linking to emails in the UI
- Many miscellaneous bugfixes
For the list of issues included in this release, see the CHANGELOG.
Instead of spamming real users (or worse - customers) while you test your applications, HoldMail offers the following:
- An SMTP service that stores mails instead of relaying them for delivery.
- A web interface for searching and viewing of those emails.
- A REST API to query and fetch email content, very useful for testing.
- The ability to manually release(forward) individually selected mails to the real world.
If you just want to try it out, grab and install the RPM from the 'rpm' folder here:
After installation, start the holdmail service:
#> sudo /etc/init.d/holdmail start
or
#> sudo service holdmail start
It's now ready to use! Without any configuration, HoldMail does the following:
- It accepts SMTP messages on localhost port 25000. Configure your application to use this as the outgoing SMTP server.
- It makes the webapp available at http://localhost:8080/.
- Similarly, the REST API will be available at http://localhost:8080/rest/messages
- A H2 embedded database will be created in holdmail's home directory (/opt/holdmail).
Running a new distibution of holdmail will automatically apply any needed changes to the attached database.
❗ It's still always a good idea to make a backup first! If you just ran holdmail without configuring anything, that's going to be the H2 database file at $HOME/holdmail.mv.db
.
Endpoint Description | Method | URI | Request/Response |
---|---|---|---|
Find messages | GET | /rest/messages Query Params: 'recipient' (str) - search by email address 'size' (int) - limit response hit size 'page' (int) - pagination support |
Response: 200, application/json: a 'messages: [..]' array. |
Get message by ID | GET | /rest/messages/{id} | Response: 200, application/json: JSON object with summary attributes. |
Get original raw message | GET | /rest/messages/{id}/raw | Response: 200, text/plain: the original MIME message. |
Get message text body | GET | /rest/messages/{id}/text | Response: 200, text/plain: the text body if one was present, 404 otherwise. |
Get message HTML body | GET | /rest/messages/{id}/html | Response: 200, text/html: the HTML body if one was present, HTTP 404 otherwise. Any embedded content in the HTML will be replaced with a URI to the 'embedded content' endpoint (next) |
Get embedded content | GET | /rest/messages/{id}/content/{cid} | Response: 200, The embedded content with identifier 'cid' will be served with its related content type |
Get attachment (new in 2.0) | GET | /rest/messages/{id}/att/{att_id} | Response: 200 with the headers and content associated with the referenced attachment ID (the attachment ID is found in the attachments[] array in the /rest/messages/{id} response. |
Forward message | POST | /rest/messages/{id}/forward | Request: application/json: The recipient email, in the format: {"recipient":"[email protected]"} . Response: 202 on acceptance. |
If using the RPM deployment, HoldMail will look for an optional file called /etc/holdmail.properties
which it will use to override its default configuration.
⚡ Note: Since this is the initial release of holdmail, configuration is somewhat limited and is likely to receive some necessary cleanup/namespacing in the future. While any Spring Boot configuration is currently supported in this file, it may not be guaranteed to work in future releases. ⚡
# HTTP/REST (default is 8080)
server.port=5555
# SMTP (default is 25000)
holdmail.smtp.port=22222
HoldMail is designed to be open. There are no accounts or mailboxes to configure. Mail for any recipient will be stored and will be queryable. This is to facilitate the ease of email testing without requiring test authors/performers to perform mailbox setup in advance.
If you're going to have to expose the HTTP service to a larger group than desired, you can use spring basic configuration to lock it down:
security.basic.enabled=true
security.user.name=homer
security.user.password=mmmdonut
By default, the application will create a H2 database file called holdmail.mv.db
in the running user's home directory (this is /opt/holdmail/holdmail.mv.db
if you used the RPM intaller).
This should be good enough for most users, but if you want to use a different RDBMS such as MySQL, you can configure your own datasource. Add your configuaration to /etc/holdmail.properties
using the relevant Spring Boot DataSource properties. The following example shows how to configure to connect to a MySQL DB:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://mysql-server-host:3306/holdmail?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=holdmail
spring.datasource.password=password
-
The app manages its own database, so this user will need to have sufficient provileges to create and modify tables.
-
HoldMail doesn't distribute drivers for external databases (for reasons of distributable size, but mostly to avoid farcical licensing complications 🙈).
- If using the HoldMail RPM distribution, place your driver JAR file in
/opt/holdmail/lib
and the app will find it automatically. - To use the MySQL configuration above, you'll need to download the MySQL connector driver JAR yourself.
- If using the HoldMail RPM distribution, place your driver JAR file in
To release forwarded mails from HoldMail to the real world, you'll need to configure an external SMTP relay server. By default, HoldMail is configured with itself as the outgoing SMTP relay, so forwarded messages will just end up back in HoldMail!
⚡ This feature is in its infancy, and can be temperamental. Most real-world relays are (and should be) pretty strict and may reject, or worse, silently discard a forwarded email. A familiar "From" email may be specified, as many relays won't trust arbitrary sender addresses. Your system/network administrator may be needed to help you trace outbound delivery issues.
# the outgoing relay hostname (default: localhost)
holdmail.outgoing.smtp.server=localhost
# the outgoing relay port (default: holdmail's SMTP port)
holdmail.outgoing.smtp.port=${holdmail.smtp.port}
# the "From" header to be set on a forwarded mail (default: [email protected])
[email protected]
HoldMail's backend is a Spring Boot application, exposing a REST API and SMTP server. The UI is built with Vue.js.
To build from the command line, use:
gradle build (this builds the UI as well)
You'll find the JARs under build/libs
, with the RPM under build/rpm
.
Most modern Java-aware IDEs should be able to import build.gradle and launch the app by running the HoldMailApplication
class, but from the command line, the server can be launched in dev mode by using:
gradle bootRun
The UI can also be run in dev mode by navigating to the client/
directory and using:
npm start
Images of HoldMail are pushed to our private docker registry hosted on Bintray. The image pushed is our MySQL based image, and should be used within a docker compose or similar setup pointing to an external MySQL database. You can find an example at docker-compose.yml.
If you want to pull the container yourself, you can use docker pull spartasystems-docker-containers.bintray.io/sparta/holdmail
To build the application, including docker image and pushing to bintray, use the following gradle command:
./gradlew build docker dockerPush
If you want to push to another registry, you can use -DdockerName=your.repo/namespace/image-name
on the command line.
HoldMail is licensed under the Apache 2.0 license.
© Copyright 2016 - 2018 Sparta Systems Inc.
Sparta Systems helps customers bring products to market safely and efficiently by delivering quality management software solutions that provide control and transparency throughout the enterprise and their critical supplier network.
HoldMail is a product of Sparta's R&D department, built to help us test notification systems in our applications. Efficient and comprehensive automated testing is an integral feature of how we build software. Come work with us!.