Giter Club home page Giter Club logo

mailwhale's Introduction

Please note: as of Dec 2023, MailWhale is depcreated and not being actively maintained anymore. Please check out some of the alternatives mentioned below.

MailWhale

A bring-your-own-SMTP-server mail relay

๐Ÿ“„ Description

As a developer, chances are high that at some point you need to teach your application how to send mails. Essentially, there are two options. Either you use a professional mail sending service or you include an SMTP client library to your software and plug your own mail server.

Think of MailWhale like Mailgun, SendGrid or SMTPeter, but open source and self-hosted. Or like Postal or Cuttlefish, but less bloated and without running its own, internal SMTP server.

However, if you want the best of both worlds โ€“ that is, send mails via simple HTTP calls and with no extra complexity, but still use your own infrastructure โ€“ you may want to go with โœ‰๏ธ๐Ÿณ.

You get a simple REST API, which you can call to send out e-mail. You can plug your self-hosted SMTP server, as well as Google Mail or literally any other e-mail provider.

Stay tuned, there is a lot more to come.

๐Ÿšง Project State

The project is in a very early stage and breaking changes are likely to happen. We'd recommend to not yet use this in production or at least expect non-trivial effort required to upgrade to a new version.

For a more stable and robust alternative to MailWhale, check out postalsys/emailengine.

๐Ÿ“ฆ Installation

Compile from source

# 1. Clone repo
$ git clone https://github.com/muety/mailwhale.git

# 2. Adapt config to your needs, i.e. set your SMTP server and credentials, etc.
$ cp config.default.yml config.yml
$ vi config.yml

# 3. Compile Web UI
$ cd webui/
$ yarn && yarn build
$ cd ..
# 4. Compile API
$ go build

# 5. Run it
$ ./mailwhale

From GitHub Release

# 1. Download latest release
curl -s https://api.github.com/repos/muety/mailwhale/releases/latest | jq -r ".assets[] | select(.name|match(\"Linux_$(arch).tar.gz\")) | .browser_download_url" | wget -qi -

# 2. Extract
mkdir mailwhale
tar xf mailwhale_*.tar.gz -C mailwhale
cd mailwhale

# 3.[Optional] Adapt config to your needs, i.e. set your SMTP server and credentials, etc.
# vi config.yml

# 4. Run it
./mailwhale

With Docker Image

$ docker run -d \
  -p 127.0.0.1:3000:3000 \
  -v "$(pwd)/config.yml":/app/config.yml:ro \
  -v mailwhale_data:/data \
  --name mailwhale \
  ghcr.io/muety/mailwhale

Build custom Docker Image

# 1. Clone repo
$ git clone https://github.com/muety/mailwhale.git

# 2. Adapt config to your needs, i.e. set your SMTP server and credentials, etc.
$ cp config.default.yml config.yml
$ vi config.yml

# 3. Build image
$ docker build -t mailwhale .

# 4. Create persistent volume
$ docker volume create mailwhale_data

# 5. Run
$ docker run -d \
  -p 127.0.0.1:3000:3000 \
  -v "$(pwd)/config.yml":/app/config.yml:ro \
  -v mailwhale_data:/data \
  --name mailwhale \
  mailwhale

Note: An official Docker image is about to come. Also, there will be no need to mount your config file into the container, as everything will be configurable using environment variables eventually.

Reverse Proxy

To run this app behind a reverse proxy, see here for example configurations for different web servers (works analogously for MailWhale). In addition, MW_WEB_PUBLIC_URL (or web.public_url, respectively) must be configured accordingly (set to the absolute URL of your MailWhale instance). Also see #43.

โŒจ๏ธ Usage

First of all, you can get most tasks done through the web UI, available at http://localhost:3000.

1. Define a user

To get started with MailWhale, you need to create a user first. To do so, register a new user API or web UI. security.allow_signup needs to be set to true.

2. Create an API client

It is good practice to not authenticate against the API as a user directly. Instead, create an API client with limited privileges, that could easily be revoked in the future. A client is identified by a client ID and a client secret (or token), very similar to what you might already be familiar with from AWS APIs. Usually, such a client corresponds to an individual client application of yours, which wants to access MailWhale's API.

Request

$ curl -XPOST \
     -u '[email protected]:admin' \
     -H 'Content-Type: application/json' \
     --data-raw '{
         "description": "My juicy web app",
         "sender": "Epic Juice Store <[email protected]>",
         "permissions": ["send_mail"]
     }' \
     'http://localhost:3000/api/client'

Response

{
    "id": "SVNORFBUWGhxWGZSUUl0eA==",
    "description": "My juicy web app",
    "permissions": [
        "send_mail"
    ],
    "sender": "Epic Juice Store <[email protected]>",
    "api_key": "75c74447-c4af-453b-ad06-3a8ae969ed16"
}

The response contains your new client's ID (id) and secret (api_key). Remember these credentials, as they are needed for subsequent requests from your application.

Client authentication happens through HTTP basic auth. Most HTTP clients support basic auth out of the box (including cURL with its -u parameter). If your's doesn't, you can hash create the hash like so:

$ echo "Authorization: Basic $(echo '<client_id>:<client_secret>' | base64)"

# Result:
# Authorization: Basic U1ZOT1JGQlVXR2h4V0daU1VVbDBlQT09Ojc1Yzc0NDQ3LWM0YWYtNDUzYi1hZDA2LTNhOGFlOTY5ZWQxNg==

3. Send E-Mails

Plain text or HTML

$ curl -XPOST \
  -u '<client_id>:<client_secret>' \
  -H 'content-type: application/json' \
  --data '{
      "to": ["Jane Doe <[email protected]>"],
      "subject": "Dinner tonight?",
      "html": "<h1>Hey you!</h1><p>Wanna have dinner tonight?</p>"
  }' \
  'http://localhost:3000/api/mail'

You can also a text field instead, to send a plain text message.

Using a template

In case you have created a template using the web UI, you can reference it in a new mail like so:

$ curl -XPOST \
  -u '<client_id>:<client_secret>' \
  -H 'content-type: application/json' \
  --data '{
      "to": ["Jane Doe <[email protected]>"],
      "subject": "Dinner tonight?",
      "template_id": "8033ea08-2630-408b-82f9-d38b403243d0",
      "template_vars: {
        "text.greeting": "Hello new user!",
    }
  }' \
  'http://localhost:3000/api/mail'

๐Ÿ”ง Configuration Options

You can specify configuration options either via a config file (config.yml) or via environment variables. Here is an overview of all options.

YAML Key Environment Variable Default Description
env MW_ENV dev Whether to use development- or production settings
mail.domain MW_MAIL_DOMAIN - Default domain for sending mails
web.listen_addr MW_WEB_LISTEN_ADDR 127.0.0.1:3000 IP and port for the web server to listen on (can be IPv4 or IPv6)
web.cors_origin - [http://localhost:5000] List of URLs which to accept CORS requests for
web.public_url MW_PUBLIC_URL http://localhost:3000 The URL under which your MailWhale server is available from the public internet
smtp.host MW_SMTP_HOST - SMTP relay host name or IP
smtp.port MW_SMTP_PORT - SMTP relay port
smtp.username MW_SMTP_USER - SMTP relay authentication user name (leave blank to disable authentication)
smtp.password MW_SMTP_PASS - SMTP relay authentication password
smtp.tls MW_SMTP_TLS false Whether to require full TLS (not to be confused with STARTTLS) for the SMTP relay
smtp.skip_verify_tls MW_SMTP_SKIP_VERIFY_TLS false Whether to skip certificate verification (e.g. trust self-signed certs)
store.path MW_STORE_PATH ./data.json.db Target location of the database file
security.pepper MW_SECURITY_PEPPER - Pepper to use for hashing user passwords
security.allow_signup MW_SECURITY_ALLOW_SIGNUP true Whether to allow the registration of new users
security.verify_users MW_SECURITY_VERIFY_USERS true Whether to require new users to activate their account using a confirmation mail
security.verify_senders MW_SECURITY_VERIFY_SENDERS true Whether to validate sender addresses and their domains' SPF records
security.block_list MW_SECURITY_BLOCK_LIST [] List of regexes used to block certain recipient addresses

Sender verification & SPF Check

By default, mails are sent using a randomly generated address in the From header, which belongs to the domain configured via mail.domain (i.e. [email protected]). Optionally, custom sender addresses can be configured on a per-API-client basis. However, it is recommended to properly configure SPF on that custom domain and instruct MailWhale to verify that configuration.

As a user, you need to configure your domain, which you want to use as part of your senders address (e.g. example.org for sending mails from User Server <[email protected]>), to publish an SPF record that delegates to the domain under which MailWhale is running (e.g. mailwhale.dev).

example.org.  IN  TXT v=spf1 include:mailwhale.dev

As a server operator of a MailWhale instance, you need to enable mail.verify_senders and set your mail.domain and web.public_url. For that domain, you need to configure an SPF record that allows your SMTP relay provider's (e.g. Mailbox.org, GMail, SendGrid, etc.) mail servers to be senders. Refer to your provider's documentation, e.g. this.

๐Ÿš€ Features (planned)

Right now, this app is very basic. However, there are several cool features on our roadmap.

  • Bounce handling: Ultimately, we want to offer the ability to plug an IMAP server in addition, to get notified about bounced / undelivered mails.
  • Statistics: There will be basic statistics about when which client has sent how many mails, how many were successful or were bounced, etc.
  • Client libraries: To make the developer experience even smoother, client SDKs for different programming languages will we added some time.
  • Minor enhancements: IPv6- and TLS support, API documentation, ...

๐Ÿ““ License

MIT

mailwhale's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mailwhale's Issues

How to create user via the API?

Hi! The README mentions:

To get started with MailWhale, you need to create a user first. To do so, register a new user API or web UI.

Would you be able to provide an example API request for registering a new user using the API? Thanks in advance.

E-Mail / domain blacklist

Could either be per-client and configurable at runtime (using API or web UI) or a server-wide config setting (requires restart). I'd say the latter is sufficient.

I am here to contribute

Hi!

I can across MailWhale when I was trying to find open source alternative to SendGrid. I also was considering to use Postal but due to its complexity I was thinking to creating something like that in Go and Svelte. Fortunately, in particular project has both. I am happy that I came across this project.

As this project is at its early stage of the development, I was hoping if I can help in the development in any way possible. I am interested and wanting to contribute. So if you have any work to assign to anyone please feel free to let me know.

Whitelist for allowed sender domains per user

A server admin may be required to explicitly specify for a user, which domains she may use in sender addresses, regardless of whether the SPF check fails or not.

Most e-mail providers (including Mailbox.org and Mailjet) require to verify the ownership of a new sender address before allowing to send mail from it. As most of these providers won't have an API, that MailWhale could call, this verification step is something a MailWhale admin would have to do manually.

Also, add some documentation on this to the clients page.

User activation as a Service

Simple API to let MailWhale handle user actications on behalf of your application.

  1. App X requests to send a confirmation mail to newly signed up user with some e-mail address
  2. MailWhale generates and persists confirmation token for that user and sends out a mail with a link
  3. MailWhale handles the link click and changes the status of the user (so it can actively be requested later on)
  4. Optionally, a pre-defined webhook is a called to notify app X about to successful activation

Set application version at compile time

@b3n4kh proposed a pretty cool way for managing version information by setting the version tag right at compile time, see #39 (comment). This way, we could get rid of version.txt.

I'd love to have this:

  • By default, version is set to development or something
  • If a Git tag (and a Git repo in the first place) is available and attached to the very latest commit, set version to that tag at compile time
  • If a Git tag is available, but attached to a previous commit (other than HEAD), set application version to <latest-tag>-<latest-commit-hash>, e.g. 1.0.0-df44f7f

The third point is not a "must-have", if too hard to realize, though.

@b3n4kh Feel free to give it a go, if you want.

How to create the smtp server?

While trying this project in my local, when I try to signup for the first time it tries to send an email for the verification. That email is not getting sent because there is nothing running on localhost:465. I was thinking that this project will provide the SMTP server as well. If not by this project, then can you please tell me how can I run an SMTP server on my local which sends the email?

Website Dashbord isn't loading

Hello, I've sucessfully installed everything and are able to run it without ny issue, when i visit the site then in the console it give the statuscode 200. the website title changed correctly to Mailwhale BUT the page is just blank without any content. Aftr inspecting the HTML of the Pageit seem like there is nothing:
grafik

Now i tried to disable adblock or any other extension which could cause this but sadly did not help. I even tried to visit the site on another machine but the issue is always the same.

Note that i changed all 127.0,0.1 in the config to 0.0.0.0 so i can access it outside of the host (cause my linux server don't have an display installed)

Hopefully someone can help me there,

Regards,
FuckingToasters

can't log in

so..I've done everything, the server is running....but I can't even log into my own instance

Bounce handler idea

I have been thinking how you can implement a bounce handler quickly and safely.

With this article as reference: https://serverfault.com/questions/48326/how-to-collect-bounces-in-postfix

You could make a simple API endpoint that will wait for the mail server to send a bounce API request.

So the flow would look something like this:

postfix receives bounce -> bounce handler script processes the incoming mail bounce -> sends request via API to mailwhale with bounce info -> user is then informed etc
Every email has a unique ID when sent. So it would be easy to track.

Option to trust self-signed certificates

Hi,

Would there be a way to prevent TLS/SSL certificate verification.

Seams that changes to the config.yml are not working.

Have set the following:
security:
pepper: '123456'
allow_signup: true
verify_users: false
verify_senders: false

But the system still attempts to send the verification email that subsequently fails due to the SMTP relay using a self signed certificate.

ยฑ |master โœ“| โ†’ docker logs mailwhale
2022-05-25T10:09:57.380930606Z [INFO ] ---
2022-05-25T10:09:57.380955667Z [INFO ] This instance is assumed to be publicly accessible at: http://localhost:3000
2022-05-25T10:09:57.380958788Z [INFO ] User registration enabled: true
2022-05-25T10:09:57.380960534Z [INFO ] Account activation required: true
2022-05-25T10:09:57.380962025Z [INFO ] Sender address verification required: true
2022-05-25T10:09:57.380963458Z [INFO ] ---
2022-05-25T10:09:57.382765931Z [INFO ] web server started, listening on 0.0.0.0:3000
.
.
.
2022-05-25T10:10:45.912522437Z [INFO ] created user '[email protected]'
2022-05-25T10:10:45.912593829Z [INFO ] [request] status=201, method=POST, uri=/api/user, duration=92.273016ms, bytes=119, addr=172.17.0.1:51922
2022-05-25T10:10:45.934366226Z [INFO ] [request] status=200, method=GET, uri=/login, duration=106.7ยตs, bytes=533, addr=172.17.0.1:51922
2022-05-25T10:10:46.124002533Z [INFO ] [request] status=304, method=GET, uri=/build/bundle.css, duration=58.916ยตs, bytes=0, addr=172.17.0.1:51922
2022-05-25T10:10:46.124411257Z [INFO ] [request] status=304, method=GET, uri=/build/bundle.js, duration=59.983ยตs, bytes=0, addr=172.17.0.1:51924
2022-05-25T10:11:07.18150931Z [ERROR] failed to send user verification to '[email protected]': x509: certificate signed by unknown authority

Please advise if a way exists to disable that check or to trust that certificate or a method to disable the activation / verification requirements.

Allow to run under subpath with reverse proxy

Love this project! trying to setup a reverse proxy using sub directory. Was wondering if mailwhale supports it?

This is the config I am using:

    location /mailwhale/ {
        proxy_pass http://127.0.0.1:3005;
        proxy_set_header Host iot.rplab.xyz;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

    }

Any hints?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.