mailkick 1.2.2 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c69391f60c043d1a2ad07d45adf6dd4dcfdfae381570e4e5c6ccc81df0d2ae6
4
- data.tar.gz: 18f7747bed0cfd2a802b0ef8464a0d25696acc873c86f2784242c9ff9a8d2db7
3
+ metadata.gz: 6a9bd60adb2d9f1ce219b451369a4c5547f3dea808fa3123e31fb317fccfe843
4
+ data.tar.gz: 9fab1707325fdc093ddc9123c94d331d6c7b4b17ceaae1d5f8760cdb30b4f74b
5
5
  SHA512:
6
- metadata.gz: 39166cce458a3949b88ed4ebc27d49da862039830495693e955a78a7364a8ac5410d6fe4a24f6ba62de6d222e23c13f3920debab9f071223bafae0b57741c1f2
7
- data.tar.gz: 5038361e264b4d953d87d6427ef04832ac3dc724dc4f5bb9c9e8a9631e573f2baa2a5c114dd3dc343e7c655cedf3371d3f9187c3785204be895b2a020c6806df
6
+ metadata.gz: 8f1160fff3f3ef81e4ff3d2ab9fae04076e84db93f95ab17f1655a99185331c22783c262dac0433484575371bebedc05750744a1434fdfa6f9d32cac87609050
7
+ data.tar.gz: f0cfecb317f7fc74848ec9479248f635f268194bfd9d4c38ecda06cb3ec9815eb9c17d8b9044ca38ca0dd459a5e3fe9d8acfefd3d7953ded84b132bb5286a9ff
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 1.3.1 (2024-09-09)
2
+
3
+ - Fixed deprecation warning with Rails 7.1
4
+
5
+ ## 1.3.0 (2024-01-18)
6
+
7
+ - Added support for one-click unsubscribe headers (RFC 8058)
8
+
1
9
  ## 1.2.2 (2023-10-30)
2
10
 
3
11
  - Fixed error when secret key base set with `SECRET_KEY_BASE_DUMMY`
data/README.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  Email subscriptions for Rails
4
4
 
5
- - Add one-click unsubscribe links to your emails
5
+ - Add one-click unsubscribe links and headers to your emails
6
6
  - Fetch bounces and spam reports from your email service
7
7
 
8
8
  :postbox: Check out [Ahoy Email](https://github.com/ankane/ahoy_email) for analytics
9
9
 
10
- [![Build Status](https://github.com/ankane/mailkick/workflows/build/badge.svg?branch=master)](https://github.com/ankane/mailkick/actions)
10
+ [![Build Status](https://github.com/ankane/mailkick/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/mailkick/actions)
11
11
 
12
12
  ## Installation
13
13
 
@@ -81,6 +81,16 @@ rails generate mailkick:views
81
81
 
82
82
  which copies the view into `app/views/mailkick`.
83
83
 
84
+ ## Unsubscribe Headers
85
+
86
+ For one-click unsubscribe headers ([RFC 8058](https://datatracker.ietf.org/doc/html/rfc8058)), create `config/initializers/mailkick.rb` with:
87
+
88
+ ```ruby
89
+ Mailkick.headers = true
90
+ ```
91
+
92
+ Headers will automatically be added to emails that call `mailkick_unsubscribe_url`.
93
+
84
94
  ## Bounces and Spam Reports
85
95
 
86
96
  Fetch bounces, spam reports, and unsubscribes from your email service. Create `config/initializers/mailkick.rb` with a method to handle opt outs.
@@ -199,68 +209,6 @@ Access the subscription model directly
199
209
  Mailkick::Subscription.all
200
210
  ```
201
211
 
202
- ## Upgrading
203
-
204
- ### 1.0
205
-
206
- Mailkick 1.0 stores subscriptions instead of opt-outs. To migrate:
207
-
208
- 1. Add a table to store subscriptions
209
-
210
- ```sh
211
- rails generate mailkick:install
212
- rails db:migrate
213
- ```
214
-
215
- 2. Change the following methods in your code:
216
-
217
- - `mailkick_user` to `has_subscriptions`
218
- - `User.not_opted_out` to `User.subscribed(list)`
219
- - `opt_in` to `subscribe(list)`
220
- - `opt_out` to `unsubscribe(list)`
221
- - `opted_out?` to `!subscribed?(list)`
222
-
223
- 3. Add a user and list to `mailkick_unsubscribe_url`
224
-
225
- ```ruby
226
- mailkick_unsubscribe_url(user, list)
227
- ```
228
-
229
- 4. Migrate data for each of your lists
230
-
231
- ```ruby
232
- opted_out_emails = Mailkick::Legacy.opted_out_emails(list: nil)
233
- opted_out_users = Mailkick::Legacy.opted_out_users(list: nil)
234
-
235
- User.find_in_batches do |users|
236
- users.reject! { |u| opted_out_emails.include?(u.email) }
237
- users.reject! { |u| opted_out_users.include?(u) }
238
-
239
- now = Time.now
240
- records =
241
- users.map do |user|
242
- {
243
- subscriber_type: user.class.name,
244
- subscriber_id: user.id,
245
- list: "sales",
246
- created_at: now,
247
- updated_at: now
248
- }
249
- end
250
-
251
- # use create! for Active Record < 6
252
- Mailkick::Subscription.insert_all!(records)
253
- end
254
- ```
255
-
256
- 5. Drop the `mailkick_opt_outs` table
257
-
258
- ```ruby
259
- drop_table :mailkick_opt_outs
260
- ```
261
-
262
- Also, if you use `Mailkick.fetch_opt_outs`, [add a method](#bounces-and-spam-reports) to handle opt outs.
263
-
264
212
  ## History
265
213
 
266
214
  View the [changelog](https://github.com/ankane/mailkick/blob/master/CHANGELOG.md)
@@ -1,6 +1,7 @@
1
1
  module Mailkick
2
2
  class SubscriptionsController < ActionController::Base
3
3
  protect_from_forgery with: :exception
4
+ skip_forgery_protection only: [:unsubscribe]
4
5
 
5
6
  before_action :set_subscription
6
7
 
@@ -12,7 +13,13 @@ module Mailkick
12
13
 
13
14
  Mailkick::Legacy.opt_out(legacy_options) if Mailkick::Legacy.opt_outs?
14
15
 
15
- redirect_to subscription_path(params[:id])
16
+ if request.post? && params["List-Unsubscribe"] == "One-Click"
17
+ # must not redirect according to RFC 8058
18
+ # could render show action instead
19
+ render plain: "Unsubscribe successful"
20
+ else
21
+ redirect_to subscription_path(params[:id])
22
+ end
16
23
  end
17
24
 
18
25
  def subscribe
data/config/routes.rb CHANGED
@@ -6,7 +6,7 @@ end
6
6
 
7
7
  Mailkick::Engine.routes.draw do
8
8
  resources :subscriptions, only: [:show] do
9
- get :unsubscribe, on: :member
9
+ match :unsubscribe, on: :member, via: [:get, :post]
10
10
  get :subscribe, on: :member
11
11
  end
12
12
  end
@@ -13,7 +13,7 @@ module Mailkick
13
13
  creds =
14
14
  if app.respond_to?(:credentials) && app.credentials.secret_key_base
15
15
  app.credentials
16
- elsif app.respond_to?(:secrets)
16
+ elsif app.respond_to?(:secrets) && (Rails::VERSION::STRING.to_f < 7.1 || app.config.paths["config/secrets"].existent.any?)
17
17
  app.secrets
18
18
  else
19
19
  app.config
@@ -3,7 +3,7 @@ module Mailkick
3
3
  def has_subscriptions
4
4
  class_eval do
5
5
  has_many :mailkick_subscriptions, class_name: "Mailkick::Subscription", as: :subscriber
6
- scope :subscribed, -> (list) { joins(:mailkick_subscriptions).where(mailkick_subscriptions: {list: list}) }
6
+ scope :subscribed, ->(list) { joins(:mailkick_subscriptions).where(mailkick_subscriptions: {list: list}) }
7
7
 
8
8
  def subscribe(list)
9
9
  mailkick_subscriptions.where(list: list).first_or_create!
@@ -6,7 +6,7 @@ module Mailkick
6
6
  REASONS_MAP = {
7
7
  "SpamNotification" => "spam",
8
8
  "SpamComplaint" => "spam",
9
- "Unsubscribe" => "unsubscribe",
9
+ "Unsubscribe" => "unsubscribe"
10
10
  }
11
11
 
12
12
  def initialize(options = {})
@@ -2,7 +2,12 @@ module Mailkick
2
2
  module UrlHelper
3
3
  def mailkick_unsubscribe_url(subscriber, list, **options)
4
4
  token = Mailkick.generate_token(subscriber, list)
5
- mailkick.unsubscribe_subscription_url(token, **options)
5
+ url = mailkick.unsubscribe_subscription_url(token, **options)
6
+ if Mailkick.headers && headers["List-Unsubscribe"].nil?
7
+ headers["List-Unsubscribe-Post"] ||= "List-Unsubscribe=One-Click"
8
+ headers["List-Unsubscribe"] = "<#{url}>"
9
+ end
10
+ url
6
11
  end
7
12
  end
8
13
  end
@@ -1,3 +1,3 @@
1
1
  module Mailkick
2
- VERSION = "1.2.2"
2
+ VERSION = "1.3.1"
3
3
  end
data/lib/mailkick.rb CHANGED
@@ -24,12 +24,13 @@ require_relative "mailkick/version"
24
24
  require_relative "mailkick/engine" if defined?(Rails)
25
25
 
26
26
  module Mailkick
27
- mattr_accessor :services, :mount, :process_opt_outs_method
27
+ mattr_accessor :services, :mount, :process_opt_outs_method, :headers
28
28
  mattr_reader :secret_token
29
29
  mattr_writer :message_verifier
30
30
  self.services = []
31
31
  self.mount = true
32
32
  self.process_opt_outs_method = ->(_) { raise "process_opt_outs_method not defined" }
33
+ self.headers = false
33
34
 
34
35
  def self.fetch_opt_outs
35
36
  services.each(&:fetch_opt_outs)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailkick
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-30 00:00:00.000000000 Z
11
+ date: 2024-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -75,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  requirements: []
78
- rubygems_version: 3.4.10
78
+ rubygems_version: 3.5.16
79
79
  signing_key:
80
80
  specification_version: 4
81
81
  summary: Email subscriptions for Rails