项目作者: SchumacherFM

项目描述 :
mailout - a https://caddyserver.com/ V1 SMTP client email middleware with PGP encryption
高级语言: Go
项目地址: git://github.com/SchumacherFM/mailout.git
创建时间: 2016-01-26T19:59:26Z
项目社区:https://github.com/SchumacherFM/mailout

开源协议:Apache License 2.0

下载


``` A jQuery AJAX handler might look like (untested): ``` $(document).ready(function() { $('#myContactForm').submit(function(event) { $.ajax({ type : 'POST', url : 'https://myCaddyServer.com/mailout', data : $('#myContactForm').serialize(), dataType : 'json', encode : true }) .done(function(data) { console.log(data); $('#contactThankYou').show(); $('#myContactForm').hide(); }) .fail(function() { alert( "error" ); }); event.preventDefault(); }); }); ``` An email template for an outgoing mail may look like in plain text: ``` Hello, please find below a new contact: Name {{.Form.Get "name"}} Email {{.Form.Get "email"}} Message: {{.Form.Get "message"}} User Agent: {{.Form.Get "user_agent"}} ``` ### HTML Form Fields A must-have form field is the email address: `` or for HTML5 `` Optional field should be `name`: `` Both fields will be merged to the `From` Email address: `"name" `. If you do not provide the name field, only the email address will be used. If a `redirect_field` has been configured and the form contains a matching field, its value will be used to redirect the user's browser after successful form submission. ### Testing #### JavaScript To do a quick test of the configuration for mailout on your Caddy server, the following plain vanilla JavaScript using XMLHttpRequest does the job. ``` var xhr = new XMLHttpRequest(); xhr.open('POST', '/mailout'); // Change if /mailout is not your configured endpoint xhr.onreadystatechange = function () { console.log(this.responseText); } // Use this header for the paramater format below xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); var params = 'name=Matt&email=' + encodeURIComponent('matt@github.com'); // Send the email xhr.send(params); ``` #### CURL If you are on a commandline console, the following CURL command also issues a POST request with the name and email fields: ``` curl http://example.com/mailout -d 'name=Matt&email=matt@github.com' ``` ### GMail If you use Gmail as outgoing server these pages can help: - [Google SMTP settings to send mail from a printer, scanner, or app](https://support.google.com/a/answer/176600) - [Allowing less secure apps to access your account](https://support.google.com/accounts/answer/6010255) I need some help to pimp the authentication feature of [gomail](https://github.com/go-gomail/gomail/blob/master/smtp.go#L41) to avoid switching on the less secure "feature". # Todo - file uploads - implement ideas and improvements from open issues CORS please use the dedicated Caddy module for handling CORS requests. # Contribute Send me a pull request or open an issue if you encounter a bug or something can be improved! Multi-time pull request senders gets collaborator access. # License [Cyrill Schumacher](https://github.com/SchumacherFM) - [My pgp public key](https://www.schumacher.fm/cyrill.asc) Copyright 2016 Cyrill Schumacher All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

mailout - SMTP Client with PGP for Caddy v1

Post form data from a website to this route and receive the data as nicely
formatted email.

Supports Caddy, the web server: >= v0.9 < 2

Read more: https://cyrillschumacher.com/projects/2016-02-26-mailout-caddyserver-email-smtp/

Mailout config options in the Caddyfile:

  1. mailout [endpoint] {
  2. maillog [path/to/logdir|stdout|stderr]
  3. errorlog [path/to/logdir|stdout|stderr]
  4. to email@address1.tld
  5. [cc "email@address2.tld, email@addressN.tld"]
  6. [bcc "email@addressN.tld, email@addressN.tld"]
  7. subject "Email from {{.firstname}} {{.lastname}}"
  8. body path/to/tpl.[txt|html]
  9. [from_email optional.senders@email.address]
  10. [from_name "Optional Senders Name"]
  11. [email@address1.tld path/to/pgp1.pub|ENV:MY_PGP_KEY_PATH_1|https://keybase.io/cyrill1/key.asc]
  12. [email@address2.tld path/to/pgp2.pub|ENV:MY_PGP_KEY_PATH_2|https://keybase.io/cyrill2/key.asc]
  13. [email@addressN.tld path/to/pgpN.pub|ENV:MY_PGP_KEY_PATH_N|https://keybase.io/cyrillN/key.asc]
  14. username "ENV:MY_SMTP_USERNAME|gopher"
  15. password "ENV:MY_SMTP_PASSWORD|g0ph3r"
  16. host "ENV:MY_SMTP_HOST|smtp.gmail.com"
  17. port ENV:MY_SMTP_PORT|25|465|587
  18. [ratelimit_interval 24h]
  19. [ratelimit_capacity 1000]
  20. [skip_tls_verify]
  21. [redirect_field "optional name of form field used for redirection url"]
  22. [captcha]
  23. [recaptcha]
  24. recaptcha_secret [reCAPTCHA Secret key of your site]
  25. }

Configuration values in brackets are optional.

  • endpoint: Can be any path but your POST request must match it. Default path:
    /mailout
  • [email-address]: if provided mails get encrypted. Set a path to a file, an
    environment variable or an URL to a key on a HTTPS site. Key = email address;
    value = PGP Key
  • maillog: Specify a directory, which gets created recursively, and emails will
    be written in there, as a backup. Leaving the maillog setting empty does not log
    anything. Every sent email is saved into its own file. Strict file permissions
    apply. If set to the value “stderr” or “stdout” (without the quotations), then
    the output will forwarded to those file descriptors.
  • errorlog: Specify a directory, which gets created recursively, and errors gets
    logged in there. Leaving the errorlog setting empty does not log anything.
    Strict file permissions apply. If set to the value “stderr” or “stdout” (without
    the quotations), then the output will forwarded to those file descriptors.
  • to, cc, bcc: Multiple email addresses must be separated by a colon and within
    double quotes.
  • subject: Has the same functionality as the body template, but text only.
  • body: Text or HTML template stored on the hard disk of your server. More
    details below.
  • from_email: Email address of the sender, otherwise the email address of the
    HTML form from the front end gets used.
  • from_name: Name of the sender. If empty the email address in the field
    from_email gets used.
  • username, password, host: Self explanatory, access credentials to the SMTP
    server.
  • port: Plain text on port 25, SSL uses port 465, for TLS use port 587.
    Internally for TLS the host name gets verified with the certificate of the SMTP
    server.
  • ratelimit_interval: the duration in which the capacity can be consumed. A
    duration string is a possibly signed sequence of decimal numbers, each with
    optional fraction and a unit suffix, such as “300ms”, “1.5h” or “2h45m”. Valid
    time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. Default: 24h
  • ratelimit_capacity: the overall capacity within the interval. Default: 1000
  • skip_tls_verify if added skips the TLS verification process otherwise
    hostnames must match.
  • redirect_field: Form field name to use to configure redirection URL.

The default filename for an encrypted message attached to an email is:
encrypted.gpg.

The extension .gpg has been chosen to allow easy handling with
https://www.gnupg.org/

If you don’t like this file name you can overwrite it with the key
publickeyAttachmentFileName.

To implement a fully working This is an OpenPGP/MIME encrypted message (RFC
4880 and 3156)
PGP attachment, I need some help. It’s possible that the gomail
package needs to be refactored.

Note on sensitive information leakage when using PGP with multiple email message
receivers: For each email address in the to, cc and bcc field you must add a
public PGP key, if not, emails to recipients without a public key won’t be
encrypted. For all email addresses with a PGP key, the mailout middleware will
send a separated email encrypted with the key of the receiver.

Rate limit: Does not require external storage since it uses an algorithm called
Token Bucket (Go library:
juju/ratelimit)
.

Note: Current architecture of the mailout pluging allows to set only one
endpoint and its configuration per virtual host. If you need more endpoints, for different email receivers, you must create additional virtual hosts in
*Caddy.

JSON API

Server response on success (Status 200 OK):

  1. {"code":200}

Server response on error (Status 422 Unprocessable Entity):

  1. {"code":422,"error":"Invalid email address: \"doe.john40nonexistantServer.email\""}

Server response on non-POST requests (Status 405 Method Not Allowed):

  1. {"code":405,"error":"Method Not Allowed"}

Server response on form parse error (Status 400 Bad Request):

  1. {"code":400,"error":"Bad request"}

Server response on reaching the rate limit (Status 429 Too Many Requests):

  1. {"code":429,"error":"Too Many Requests"}

Server response on internal errors:

  1. 500 Internal Server Error

Captcha

Example:

add to config: captcha

  1. <div class="form-group text-center">
  2. <img id="captcha" src="/mailout/captcha">
  3. <input type="text" id="captcha_text" name="captcha_text" class="form-control" placeholder="Captcha text" required>
  4. </div>

After sending the request:

  1. var d = new Date();
  2. $("#captcha").attr("src", "/mailout/captcha?" + d.getTime());

https://github.com/steambap/captcha

https://github.com/quasoft/memstore

ReCaptcha

Example:

add to config: recaptcha and recaptcha_secret

  1. recaptcha
  2. recaptcha_secret 6LdnR1QUAAAAAIdxxxxxxxxxxxxx

Demo recaptcha + captcha

Email template

The rendering engine for the email templates depends on the suffix of the
template file name.

HTML form

Create a simple HTML form with some JavaScript and AJAX functions.

Mandatory input field is email. Optional recommended field: name. Those two
fields will be later joined to create the From: header of an email.

The following snipped has been extracted from a Hugo
template.

```html

Thank you for contacting us!