ahoy_email 2.5.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa1850e7d07ec2fe43003f8e6c2046a10bd8229c6e5e8d12849cc8a2d819f670
4
- data.tar.gz: 4eefd3654e671eb6c65b064025d9ea5c7dd7810d73f12bbc8b34cafb2e5e00f4
3
+ metadata.gz: d7ace81db2d79de0385596b9cc076ce32f7ead8b0ac96f18be9d4df728814332
4
+ data.tar.gz: 2cf40755b20d6acf97e1d5d88d1b58da2d0de85647bd34f02c734ae2366275fa
5
5
  SHA512:
6
- metadata.gz: 0e021685e661cbb627a5d95fde8dfccbc0630398a391eea319d64ce268f3219918a6442a23f1ed9a2a06b69761a97f09aa8cb2a633e282affc200e4ac45b7d7b
7
- data.tar.gz: 104b6dfebf8f9d3bb3381e09b972708f539122ff2ca062cfc0aaf5a5af529661e06c196dfa35e862a8709b2ede56af3dcf13af9ee1bb15552ce036323ced9f39
6
+ metadata.gz: 7f7051e5893e5a489cacb2f3b76f238fb448d1065ba3fe12c02b36b89515bd591b42243ccb03e9a056b7d64f2c1a8da558d2c25135dab2db5a202261ac81f24b
7
+ data.tar.gz: ec4ece8d9c5becd279980fc72c3fe046a20a8305b41eb7df8fc9fc0cc61e8ff29dc3f0020dc929332a9551bcb13a3d569c95f2a7f277ae5f695224a656b972bf
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 3.0.0 (2025-07-02)
2
+
3
+ See the [upgrade notes](https://github.com/ankane/ahoy_email?tab=readme-ov-file#30)
4
+
5
+ - Switched to HTML5 parsing by default (when available)
6
+ - Removed support for legacy secret token generation
7
+
1
8
  ## 2.5.0 (2025-05-04)
2
9
 
3
10
  - Removed support for Ruby < 3.2 and Rails < 7.1
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2023 Andrew Kane
1
+ Copyright (c) 2014-2025 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  First-party email analytics for Rails
4
4
 
5
+ **Ahoy Email 3.0 was recently released** - see [how to upgrade](#upgrading)
6
+
5
7
  :fire: For web and native app analytics, check out [Ahoy](https://github.com/ankane/ahoy)
6
8
 
7
9
  :bullettrain_side: To manage email subscriptions, check out [Mailkick](https://github.com/ankane/mailkick)
@@ -324,14 +326,20 @@ Get stats for a campaign
324
326
  AhoyEmail.stats("my-campaign")
325
327
  ```
326
328
 
327
- ## HTML Parsing
329
+ ## Upgrading
330
+
331
+ ### 3.0
332
+
333
+ Links that use click analytics created before version 2.3.0 (released June 2024) will no longer work by default. To restore support, [determine the previous secret token](https://github.com/ankane/ahoy_email/blob/v2.5.0/lib/ahoy_email/engine.rb#L11-L21) and create an initializer with:
328
334
 
329
- By default, Nokogiri’s default HTML parser is used to rewrite links for UTM tagging and click analytics. This currently uses HTML4, which [only allows inline elements inside links](https://github.com/sparklemotion/nokogiri/issues/1876#issuecomment-468276937).
335
+ ```ruby
336
+ AhoyEmail.secret_token = [AhoyEmail.secret_token, previous_secret_token]
337
+ ```
330
338
 
331
- To use HTML5 parsing, create `config/initializers/ahoy_email.rb` with:
339
+ Also, Nokogiri’s HTML5 parser is now used to rewrite links for UTM tagging and click analytics when available. To use HTML4 parsing, create an initializer with:
332
340
 
333
341
  ```ruby
334
- AhoyEmail.default_options[:html5] = true
342
+ AhoyEmail.default_options[:html5] = false
335
343
  ```
336
344
 
337
345
  ## History
@@ -3,26 +3,7 @@ require "rails/engine"
3
3
  module AhoyEmail
4
4
  class Engine < ::Rails::Engine
5
5
  initializer "ahoy_email" do |app|
6
- AhoyEmail.secret_token ||= begin
7
- tokens = []
8
- tokens << app.key_generator.generate_key("ahoy_email")
9
-
10
- # TODO remove in 3.0
11
- creds =
12
- if app.respond_to?(:credentials) && app.credentials.secret_key_base
13
- app.credentials
14
- elsif app.respond_to?(:secrets) && app.config.paths["config/secrets"].existent.any?
15
- app.secrets
16
- else
17
- app.config
18
- end
19
-
20
- token = creds.respond_to?(:secret_key_base) ? creds.secret_key_base : creds.secret_token
21
- token ||= app.secret_key_base # should come first, but need to maintain backward compatibility
22
- tokens << token
23
-
24
- tokens
25
- end
6
+ AhoyEmail.secret_token ||= app.key_generator.generate_key("ahoy_email")
26
7
  end
27
8
  end
28
9
  end
@@ -101,7 +101,11 @@ module AhoyEmail
101
101
  when false
102
102
  Nokogiri::HTML4::Document
103
103
  else
104
- Nokogiri::HTML::Document
104
+ if defined?(Nokogiri::HTML5::Document)
105
+ Nokogiri::HTML5::Document
106
+ else
107
+ Nokogiri::HTML4::Document
108
+ end
105
109
  end
106
110
  end
107
111
 
@@ -20,6 +20,7 @@ module AhoyEmail
20
20
  secret_tokens.any? do |secret_token|
21
21
  expected_signature =
22
22
  if legacy
23
+ # TODO remove legacy support in 4.0
23
24
  OpenSSL::HMAC.hexdigest("SHA1", secret_token, url)
24
25
  else
25
26
  signature(token: token, campaign: campaign, url: url, secret_token: secret_token)
@@ -1,3 +1,3 @@
1
1
  module AhoyEmail
2
- VERSION = "2.5.0"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -14,6 +14,14 @@ module Ahoy
14
14
  def migration_version
15
15
  "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
16
16
  end
17
+
18
+ def primary_key_type
19
+ ", id: :#{key_type}" if key_type
20
+ end
21
+
22
+ def key_type
23
+ Rails.configuration.generators.options.dig(:active_record, :primary_key_type)
24
+ end
17
25
  end
18
26
  end
19
27
  end
@@ -1,6 +1,6 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
- create_table :ahoy_clicks do |t|
3
+ create_table :ahoy_clicks<%= primary_key_type %> do |t|
4
4
  t.string :campaign, index: true
5
5
  t.string :token
6
6
  end
@@ -9,11 +9,11 @@ module Ahoy
9
9
 
10
10
  selection =
11
11
  if activerecord && mongoid
12
- puts <<-MSG
12
+ puts <<~MSG
13
13
 
14
- Which data store would you like to use?
15
- 1. Active Record (default)
16
- 2. Mongoid
14
+ Which data store would you like to use?
15
+ 1. Active Record (default)
16
+ 2. Mongoid
17
17
  MSG
18
18
 
19
19
  ask(">")
@@ -42,18 +42,10 @@ module Ahoy
42
42
  end
43
43
  end
44
44
 
45
- # TODO remove default
46
45
  def encryption
47
46
  case options[:encryption]
48
47
  when "lockbox", "activerecord", "none"
49
48
  options[:encryption]
50
- when nil
51
- if options[:unencrypted]
52
- # TODO deprecation warning
53
- "none"
54
- else
55
- "lockbox"
56
- end
57
49
  else
58
50
  abort "Error: encryption must be lockbox, activerecord, or none"
59
51
  end
@@ -74,6 +66,18 @@ module Ahoy
74
66
  def adapter
75
67
  ActiveRecord::Base.connection_db_config.adapter.to_s
76
68
  end
69
+
70
+ def primary_key_type
71
+ ", id: :#{key_type}" if key_type
72
+ end
73
+
74
+ def foreign_key_type
75
+ ", type: :#{key_type}" if key_type
76
+ end
77
+
78
+ def key_type
79
+ Rails.configuration.generators.options.dig(:active_record, :primary_key_type)
80
+ end
77
81
  end
78
82
  end
79
83
  end
@@ -19,18 +19,10 @@ module Ahoy
19
19
  end
20
20
  end
21
21
 
22
- # TODO remove default
23
22
  def encryption
24
23
  case options[:encryption]
25
24
  when "lockbox", "none"
26
25
  options[:encryption]
27
- when nil
28
- if options[:unencrypted]
29
- # TODO deprecation warning
30
- "none"
31
- else
32
- "lockbox"
33
- end
34
26
  else
35
27
  abort "Error: encryption must be lockbox or none"
36
28
  end
@@ -1,7 +1,7 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
- create_table :ahoy_messages do |t|
4
- t.references :user, polymorphic: true
3
+ create_table :ahoy_messages<%= primary_key_type %> do |t|
4
+ t.references :user<%= foreign_key_type %>, polymorphic: true
5
5
  <%= to_column %>
6
6
  t.string :mailer
7
7
  t.text :subject
@@ -13,11 +13,11 @@ module Ahoy
13
13
 
14
14
  selection =
15
15
  if activerecord && mongoid
16
- puts <<-MSG
16
+ puts <<~MSG
17
17
 
18
- Which data store would you like to use?
19
- 1. Active Record (default)
20
- 2. Mongoid
18
+ Which data store would you like to use?
19
+ 1. Active Record (default)
20
+ 2. Mongoid
21
21
  MSG
22
22
 
23
23
  ask(">")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_email
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -29,42 +29,42 @@ dependencies:
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 2.3.2
32
+ version: '2.8'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 2.3.2
39
+ version: '2.8'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: nokogiri
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '0'
46
+ version: '1.15'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: '0'
53
+ version: '1.15'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: safely_block
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: '0.4'
60
+ version: '0.5'
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: '0.4'
67
+ version: '0.5'
68
68
  email: andrew@ankane.org
69
69
  executables: []
70
70
  extensions: []