diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 0000000..f354ff0 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,755 @@ +Changelog +========= + +Anymail releases follow `semantic versioning `_. +Among other things, this means that minor updates (1.x to 1.y) +should always be backwards-compatible, and breaking changes will +always increment the major version number (1.x to 2.0). + +.. _semver: http://semver.org + + +.. This changelog is designed to be readable standalone on GitHub, + as well as included in the Sphinx docs. Do *not* use Sphinx + references; links into the docs must use absolute urls to + https://anymail.readthedocs.io/ (generally to en/stable/, though + linking to a specific older version may be appropriate for features + that have been retired). + +.. You can use docutils 1.0 markup, but *not* any Sphinx additions. + GitHub rst supports code-block, but *no other* block directives. + +.. default-role:: literal + +Current development version +--------------------------- + +Breaking changes +~~~~~~~~~~~~~~~~ + +* Drop support for Django versions older than Django 1.11. + (For compatibility back to Django 1.8, stay on the Anymail `v3.0`_ + extended support branch.) +* **SendGrid:** Remove the legacy SendGrid *v2* EmailBackend + (Anymail has defaulted to SendGrid's newer v3 API since Anymail v0.8.) + +Other +~~~~~ + +* Maintain changelog in the repository itself (rather than in GitHub release notes). + + +v3.0 +---- + +*2018-05-30* + +This is an extended support release. Anymail v3.x will receive security updates +and fixes for any breaking ESP API changes through at least April, 2019. + +Breaking changes +~~~~~~~~~~~~~~~~ + +* Drop support for Python 3.3 (see `#99`_). +* **SendGrid:** Fix a problem where Anymail's status tracking webhooks didn't always + receive the same `event.message_id` as the sent `message.anymail_status.message_id`, + due to unpredictable behavior by SendGrid's API. Anymail now generates a UUID for + each sent message and attaches it as a SendGrid custom arg named anymail_id. For most + users, this change should be transparent. But it could be a breaking change if you + are relying on a specific message_id format, or relying on message_id matching the + *Message-ID* mail header or SendGrid's "smtp-id" event field. (More details in the + `docs `__; + also see `#108`_.) Thanks to `@joshkersey`_ for the report and the fix. + +Features +~~~~~~~~ + +* Support Django 2.1 prerelease. + +Fixes +~~~~~ + +* **Mailjet:** Fix tracking webhooks to work correctly when Mailjet "group events" + option is disabled (see `#106`_). + +Deprecations +~~~~~~~~~~~~ + +* This will be the last Anymail release to support Django 1.8, 1.9, and 1.10 + (see `#110`_). +* This will be the last Anymail release to support the legacy SendGrid v2 EmailBackend + (see `#111`_). (SendGrid's newer v3 API has been the default since Anymail v0.8.) + +If these deprecations affect you and you cannot upgrade, set your requirements to +`django-anymail~=3.0` (a "compatible release" specifier, equivalent to `>=3.0,==3.*`). + + +v2.2 +---- + +*2018-04-16* + +Fixes +~~~~~ + +* Fix a breaking change accidentally introduced in v2.1: The boto3 package is no + longer required if you aren't using Amazon SES. + + +v2.1 +---- + +*2018-04-11* + +**NOTE:** v2.1 accidentally introduced a **breaking change:** enabling Anymail webhooks +with `include('anymail.urls')` causes an error if boto3 is not installed, even if you +aren't using Amazon SES. This is fixed in v2.2. + +Features +~~~~~~~~ + +* **Amazon SES:** Add support for this ESP + (`docs `__). +* **SparkPost:** Add SPARKPOST_API_URL setting to support SparkPost EU and SparkPost + Enterprise + (`docs `__). +* **Postmark:** Update for Postmark "modular webhooks." This should not impact client + code. (Also, older versions of Anymail will still work correctly with Postmark's + webhook changes.) + +Fixes +~~~~~ + +* **Inbound:** Fix several issues with inbound messages, particularly around non-ASCII + headers and body content. Add workarounds for some limitations in older Python email + packages. + +Other +~~~~~ + +* Use tox to manage Anymail test environments (see contributor + `docs `__). + +Deprecations +~~~~~~~~~~~~ + +* This will be the last Anymail release to support Python 3.3. See `#99`_ for more + information. + + +v2.0 +---- + +*2018-03-08* + +Breaking changes +~~~~~~~~~~~~~~~~ + +* Drop support for deprecated WEBHOOK_AUTHORIZATION setting. If you are using webhooks + and still have this Anymail setting, you must rename it to WEBHOOK_SECRET. See the + `v1.4`_ release notes. +* Handle *Reply-To,* *From,* and *To* in EmailMessage `extra_headers` the same as + Django's SMTP EmailBackend if supported by your ESP, otherwise raise an unsupported + feature error. Fixes the SparkPost backend to be consistent with other backends if + both `headers["Reply-To"]` and `reply_to` are set on the same message. If you are + setting a message's `headers["From"]` or `headers["To"]` (neither is common), the + new behavior is likely a breaking change. See + `docs `__ + and `#91`_. +* Treat EmailMessage `extra_headers` keys as case-\ *insensitive* in all backends, for + consistency with each other (and email specs). If you are specifying duplicate + headers whose names differ only in case, this may be a breaking change. See + `docs `__. + +Features +~~~~~~~~ + +* **SendinBlue:** Add support for this ESP + (`docs `__). + Thanks to `@RignonNoel`_ for the implementation. +* Add EmailMessage `envelope_sender` attribute, which can adjust the message's + *Return-Path* if supported by your ESP + (`docs `__). +* Add universal wheel to PyPI releases for faster installation. + +Other +~~~~~ + +* Update setup.py metadata, clean up implementation. (Hadn't really been touched + since original Djrill version.) +* Prep for Python 3.7. + + +v1.4 +---- + +*2018-02-08* + +Security +~~~~~~~~ + +* Fix a low severity security issue affecting Anymail v0.2–v1.3: rename setting + WEBHOOK_AUTHORIZATION to WEBHOOK_SECRET to prevent inclusion in Django error + reporting. + (`CVE-2018-1000089 `__) + +*More information* + +Django error reporting includes the value of your Anymail WEBHOOK_AUTHORIZATION +setting. In a properly-configured deployment, this should not be cause for concern. +But if you have somehow exposed your Django error reports (e.g., by mis-deploying +with DEBUG=True or by sending error reports through insecure channels), anyone who +gains access to those reports could discover your webhook shared secret. An +attacker could use this to post fabricated or malicious Anymail tracking/inbound events +to your app, if you are using those Anymail features. + +The fix renames Anymail's webhook shared secret setting so that Django's error +reporting mechanism will +`sanitize `__ it. + +If you are using Anymail's event tracking and/or inbound webhooks, you should upgrade +to this release and change "WEBHOOK_AUTHORIZATION" to "WEBHOOK_SECRET" in the ANYMAIL +section of your settings.py. You may also want to +`rotate the shared secret `__ +value, particularly if you have ever exposed your Django error reports to untrusted +individuals. + +If you are only using Anymail's EmailBackends for sending email and have not set up +Anymail's webhooks, this issue does not affect you. + +The old WEBHOOK_AUTHORIZATION setting is still allowed in this release, but will issue +a system-check warning when running most Django management commands. It will be removed +completely in a near-future release, as a breaking change. + +Thanks to Charlie DeTar (`@yourcelf`_) for responsibly reporting this security issue +through private channels. + + +v1.3 +---- + +*2018-02-02* + +Security +~~~~~~~~ + +* v1.3 includes the v1.2.1 security fix released at the same time. Please review the + `v1.2.1`_ release notes, below, if you are using Anymail's tracking webhooks. + +Features +~~~~~~~~ + +* **Inbound handling:** Add normalized inbound message event, signal, and webhooks + for all supported ESPs. (See new + `Receiving mail `__ docs.) + This hasn't been through much real-world testing yet; bug reports and feedback + are very welcome. +* **API network timeouts:** For Requests-based backends (all but SparkPost), use a + default timeout of 30 seconds for all ESP API calls, to avoid stalling forever on + a bad connection. Add a REQUESTS_TIMEOUT Anymail setting to override. (See `#80`_.) +* **Test backend improvements:** Generate unique tracking `message_id` when using the + `test backend `__; + add console backend for use in development. (See `#85`_.) + + +.. _release_1_2_1: + +v1.2.1 +------ + +*2018-02-02* + +Security +~~~~~~~~ + +* Fix a **moderate severity** security issue affecting Anymail v0.2–v1.2: + prevent timing attack on WEBHOOK_AUTHORIZATION secret. + (`CVE-2018-6596 `__) + +*More information* + +If you are using Anymail's tracking webhooks, you should upgrade to this release, +and you may want to rotate to a new WEBHOOK_AUTHORIZATION shared secret (see +`docs `__). +You should definitely change your webhook auth if your logs indicate attempted exploit. + +(If you are only sending email using an Anymail EmailBackend, and have not set up +Anymail's event tracking webhooks, this issue does not affect you.) + +Anymail's webhook validation was vulnerable to a timing attack. A remote attacker +could use this to obtain your WEBHOOK_AUTHORIZATION shared secret, potentially allowing +them to post fabricated or malicious email tracking events to your app. + +There have not been any reports of attempted exploit. (The vulnerability was discovered +through code review.) Attempts would be visible in HTTP logs as a very large number of +400 responses on Anymail's webhook urls (by default "/anymail/*esp_name*/tracking/"), +and in Python error monitoring as a very large number of +AnymailWebhookValidationFailure exceptions. + + +v1.2 +---- + +*2017-11-02* + +Features +~~~~~~~~ + +* **Postmark:** Support new click webhook in normalized tracking events + + +v1.1 +---- + +*2017-10-28* + +Fixes +~~~~~ + +* **Mailgun:** Support metadata in opened/clicked/unsubscribed tracking webhooks, + and fix potential problems if metadata keys collided with Mailgun event parameter + names. (See `#76`_, `#77`_) + +Other +~~~~~ + +* Rework Anymail's ParsedEmail class and rename to EmailAddress to align it with + similar functionality in the Python 3.6 email package, in preparation for future + inbound support. ParsedEmail was not documented for use outside Anymail's internals + (so this change does not bump the semver major version), but if you were using + it in an undocumented way you will need to update your code. + + +v1.0 +---- + +*2017-09-18* + +It's official: Anymail is no longer "pre-1.0." The API has been stable +for many months, and there's no reason not to use Anymail in production. + +Breaking changes +~~~~~~~~~~~~~~~~ + +* There are no *new* breaking changes in the 1.0 release, but a breaking change + introduced several months ago in v0.8 is now strictly enforced. If you still have + an EMAIL_BACKEND setting that looks like + "anymail.backends.*espname*.\ *EspName*\ Backend", you'll need to change it to just + "anymail.backends.*espname*.EmailBackend". (Earlier versions had issued a + DeprecationWarning. See the `v0.8`_ release notes.) + +Features +~~~~~~~~ + +* Clean up and document Anymail's + `Test EmailBackend `__ +* Add notes on + `handling transient ESP errors `__ + and improving + `batch send performance `__ +* **SendGrid:** handle Python 2 `long` integers in metadata and extra headers + + +v1.0.rc0 +-------- + +*2017-09-09* + +Breaking changes +~~~~~~~~~~~~~~~~ + +* **All backends:** The old *EspName*\ Backend names that were deprecated in v0.8 have + been removed. Attempting to use the old names will now fail, rather than issue a + DeprecationWarning. See the `v0.8`_ release notes. + +Features +~~~~~~~~ + +* Anymail's Test EmailBackend is now + `documented `__ + (and cleaned up) + + +v0.11.1 +------- + +*2017-07-24* + +Fixes +~~~~~ + +* **Mailjet:** Correct settings docs. + + +v0.11 +----- + +*2017-07-13* + +Features +~~~~~~~~ + +* **Mailjet:** Add support for this ESP. Thanks to `@Lekensteyn`_ and `@calvin`_. + (`Docs `__) +* In webhook handlers, AnymailTrackingEvent.metadata now defaults to `{}`, and + .tags defaults to `[]`, if the ESP does not supply these fields with the event. + (See `#67`_.) + + +v0.10 +----- + +*2017-05-22* + +Features +~~~~~~~~ + +* **Mailgun, SparkPost:** Support multiple from addresses, as a comma-separated + `from_email` string. (*Not* a list of strings, like the recipient fields.) + RFC-5322 allows multiple from email addresses, and these two ESPs support it. + Though as a practical matter, multiple from emails are either ignored or treated + as a spam signal by receiving mail handlers. (See `#60`_.) + +Fixes +~~~~~ + +* Fix crash sending forwarded email messages as attachments. (See `#59`_.) +* **Mailgun:** Fix webhook crash on bounces from some receiving mail handlers. + (See `#62`_.) +* Improve recipient-parsing error messages and consistency with Django's SMTP + backend. In particular, Django (and now Anymail) allows multiple, comma-separated + email addresses in a single recipient string. + + +v0.9 +---- + +*2017-04-04* + +Breaking changes +~~~~~~~~~~~~~~~~ + +* **Mandrill, Postmark:** Normalize soft-bounce webhook events to event_type + 'bounced' (rather than 'deferred'). + +Features +~~~~~~~~ + +* Officially support released Django 1.11, including under Python 3.6. + + +.. _release_0_8: + +v0.8 +---- + +*2017-02-02* + +Breaking changes +~~~~~~~~~~~~~~~~ + +* **All backends:** Rename all Anymail backends to just `EmailBackend`, matching + Django's naming convention. E.g., you should update: + `EMAIL_BACKEND = "anymail.backends.mailgun.MailgunBackend" # old` + to: `EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend" # new` + + The old names still work, but will issue a DeprecationWarning and will be removed + in some future release (Apologies for this change; the old naming was a holdover + from Djrill, and I wanted to establish consistency with other Django EmailBackends + before Anymail 1.0. See `#49`_.) + +* **SendGrid:** Update SendGrid backend to their newer Web API v3. This should be a + transparent change for most projects. Exceptions: if you use SendGrid + username/password auth, Anymail's `esp_extra` with "x-smtpapi", or multiple Reply-To + addresses, please review the + `porting notes `__. + + The SendGrid v2 EmailBackend + `remains available `__ + if you prefer it, but is no longer the default. + + .. SendGrid v2 backend removed after Anymail v3.0; links frozen to that doc version + +Features +~~~~~~~~ + +* Test on Django 1.11 prerelease, including under Python 3.6. + +Fixes +~~~~~ + +* **Mandrill:** Fix bug in webhook signature validation when using basic auth via the + WEBHOOK_AUTHORIZATION setting. (If you were using the MANDRILL_WEBHOOK_URL setting + to work around this problem, you should be able to remove it. See `#48`_.) + + +v0.7 +---- + +*2016-12-30* + +Breaking changes +~~~~~~~~~~~~~~~~ + +* Fix a long-standing bug validating email addresses. If an address has a display name + containing a comma or parentheses, RFC-5322 *requires* double-quotes around the + display name (`'"Widgets, Inc." '`). Anymail now raises a new + `AnymailInvalidAddress` error for misquoted display names and other malformed + addresses. (Previously, it silently truncated the address, leading to obscure + exceptions or unexpected behavior. If you were unintentionally relying on that buggy + behavior, this may be a breaking change. See `#44`_.) In general, it's safest to + always use double-quotes around all display names. + +Features +~~~~~~~~ + +* **Postmark:** Support Postmark's new message delivery event in Anymail normalized + tracking webhook. (Update your Postmark config to enable the new event. See + `docs `__.) +* Handle virtually all uses of Django lazy translation strings as EmailMessage + properties. (In earlier releases, these could sometimes lead to obscure exceptions + or unexpected behavior with some ESPs. See `#34`_.) +* **Mandrill:** Simplify and document two-phase process for setting up + Mandrill webhooks + (`docs `__). + + +v0.6.1 +------ + +*2016-11-01* + +Fixes +~~~~~ + +* **Mailgun, Mandrill:** Support older Python 2.7.x versions in webhook validation + (`#39`_; thanks `@sebbacon`_). +* **Postmark:** Handle older-style 'Reply-To' in EmailMessage `headers` (`#41`_). + + +v0.6 +---- + +*2016-10-25* + +Breaking changes +~~~~~~~~~~~~~~~~ + +* **SendGrid:** Fix missing html or text template body when using `template_id` with + an empty Django EmailMessage body. In the (extremely-unlikely) case you were relying + on the earlier quirky behavior to *not* send your saved html or text template, you + may want to verify that your SendGrid templates have matching html and text. + (`docs `__ + -- also see `#32`_.) + +Features +~~~~~~~~ + +* **Postmark:** Add support for `track_clicks` + (`docs `__) +* Initialize AnymailMessage.anymail_status to empty status, rather than None; + clarify docs around `anymail_status` availability + (`docs `__) + + +v0.5 +---- + +*2016-08-22* + +Features +~~~~~~~~ + +* **Mailgun:** Add MAILGUN_SENDER_DOMAIN setting. + (`docs `__) + + +v0.4.2 +------ + +*2016-06-24* + +Fixes +~~~~~ + +* **SparkPost:** Fix API error "Both content object and template_id are specified" + when using `template_id` (`#24`_). + + +v0.4.1 +------ + +*2016-06-23* + +Features +~~~~~~~~ + +* **SparkPost:** Add support for this ESP. + (`docs `__) +* Test with Django 1.10 beta +* Requests-based backends (all but SparkPost) now raise AnymailRequestsAPIError + for any requests.RequestException, for consistency and proper fail_silently behavior. + (The exception will also be a subclass of the original RequestException, so no + changes are required to existing code looking for specific requests failures.) + + +v0.4 +---- + +*(not released)* + + +v0.3.1 +------ + +*2016-05-18* + +Fixes +~~~~~ + +* **SendGrid:** Fix API error that `to` is required when using `merge_data` + (see `#14`_; thanks `@lewistaylor`_). + + +v0.3 +---- + +*2016-05-13* + +Features +~~~~~~~~ + +* Add support for ESP stored templates and batch sending/merge. Exact capabilities + vary widely by ESP -- be sure to read the notes for your ESP. + (`docs `__) +* Add pre_send and post_send signals. + `docs `__ +* **Mandrill:** add support for esp_extra; deprecate Mandrill-specific message + attributes left over from Djrill. See + `migrating from Djrill `__. + + +v0.2 +---- + +*2016-04-30* + +Breaking changes +~~~~~~~~~~~~~~~~ + +* **Mailgun:** eliminate automatic JSON encoding of complex metadata values like lists + and dicts. (Was based on misreading of Mailgun docs; behavior now matches metadata + handling for all other ESPs.) +* **Mandrill:** remove obsolete wehook views and signal inherited from Djrill. See + `Djrill migration notes `__ + if you were relying on that code. + +Features +~~~~~~~~ + +* Add support for ESP event-tracking webhooks, including normalized + AnymailTrackingEvent. + (`docs `__) +* Allow get_connection kwargs overrides of most settings for individual backend + instances. Can be useful for, e.g., working with multiple SendGrid subusers. + (`docs `__) +* **SendGrid:** Add SENDGRID_GENERATE_MESSAGE_ID setting to control workarounds for + ensuring unique tracking ID on SendGrid messages/events (default enabled). + `docs `__ +* **SendGrid:** improve handling of 'filters' in esp_extra, making it easier to mix + custom SendGrid app filter settings with Anymail normalized message options. + +Other +~~~~~ + +* Drop pre-Django 1.8 test code. (Wasn't being used, as Anymail requires Django 1.8+.) +* **Mandrill:** note limited support in docs (because integration tests no + longer available). + + +v0.1 +---- + +*2016-03-14* + +Although this is an early release, it provides functional Django +EmailBackends and passes integration tests with all supported ESPs +(Mailgun, Mandrill, Postmark, SendGrid). + +It has (obviously) not yet undergone extensive real-world testing, and +you are encouraged to monitor it carefully if you choose to use it in +production. Please report bugs and problems here in GitHub. + +Features +~~~~~~~~ + +* **Postmark:** Add support for this ESP. +* **SendGrid:** Add support for username/password auth. +* Simplified install: no need to name the ESP (`pip install django-anymail` + -- not `... django-anymail[mailgun]`) + + +0.1.dev2 +-------- + +*2016-03-12* + +Features +~~~~~~~~ + +* **SendGrid:** Add support for this ESP. +* Add attach_inline_image_file helper + +Fixes +~~~~~ + +* Change inline-attachment handling to look for `Content-Disposition: inline`, + and to preserve filenames where supported by the ESP. + + +0.1.dev1 +-------- + +*2016-03-10* + +Features +~~~~~~~~ + +* **Mailgun, Mandrill:** initial supported ESPs. +* Initial docs + + +.. GitHub issue and user links + (GitHub auto-linking doesn't work in Sphinx) + +.. _#14: https://github.com/anymail/issues/14 +.. _#24: https://github.com/anymail/issues/24 +.. _#32: https://github.com/anymail/issues/32 +.. _#34: https://github.com/anymail/issues/34 +.. _#39: https://github.com/anymail/issues/39 +.. _#41: https://github.com/anymail/issues/41 +.. _#44: https://github.com/anymail/issues/44 +.. _#48: https://github.com/anymail/issues/48 +.. _#49: https://github.com/anymail/issues/49 +.. _#59: https://github.com/anymail/issues/59 +.. _#60: https://github.com/anymail/issues/60 +.. _#62: https://github.com/anymail/issues/62 +.. _#67: https://github.com/anymail/issues/67 +.. _#76: https://github.com/anymail/issues/76 +.. _#77: https://github.com/anymail/issues/77 +.. _#80: https://github.com/anymail/issues/80 +.. _#85: https://github.com/anymail/issues/85 +.. _#91: https://github.com/anymail/issues/91 +.. _#99: https://github.com/anymail/issues/99 +.. _#106: https://github.com/anymail/issues/106 +.. _#108: https://github.com/anymail/issues/108 +.. _#110: https://github.com/anymail/issues/110 +.. _#111: https://github.com/anymail/issues/111 + +.. _@calvin: https://github.com/calvin +.. _@joshkersey: https://github.com/joshkersey +.. _@Lekensteyn: https://github.com/Lekensteyn +.. _@lewistaylor: https://github.com/lewistaylor +.. _@RignonNoel: https://github.com/RignonNoel +.. _@sebbacon: https://github.com/sebbacon +.. _@yourcelf: https://github.com/yourcelf diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..4b200d1 --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1,4 @@ +.. _changelog: +.. _release_notes: + +.. include:: ../CHANGELOG.rst diff --git a/docs/index.rst b/docs/index.rst index 0733edc..17f6d0a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -32,6 +32,6 @@ Documentation :caption: About Anymail contributing - release_notes + changelog Docs privacy diff --git a/docs/release_notes.rst b/docs/release_notes.rst deleted file mode 100644 index 8f03643..0000000 --- a/docs/release_notes.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _release_notes: - -Release notes -============= - -Complete release notes can be found in the project's -`GitHub releases page`_. - -Anymail practices `semantic versioning `_. -Among other things, this means that minor updates -(1.x to 1.y) should always be backwards-compatible, -and breaking changes will always increment the -major version number (1.x to 2.0). - -.. _GitHub releases page: https://github.com/anymail/django-anymail/releases -.. _semver: http://semver.org