ahoy_email 2.1.0 → 2.1.3

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: b84f8c566d81a470ba99f4318c2d7dd3f1b3fae6b05155491f486cbdbff7c0a6
4
- data.tar.gz: 8ab62441cf6df6b4ab6af401a9cbed8864ac634d28dd728f6b83bfd743dce284
3
+ metadata.gz: b465af2a0497b6b85237fa5246c4c722d594978e07710f66ec96a9260fb44c98
4
+ data.tar.gz: 3f5e353adebbc67fbea887d9a8e36f01ba237a04d16431947855c81fc8be1bcd
5
5
  SHA512:
6
- metadata.gz: cf70b92f9ba7b0d91324eae1927fe49464c3b3a76293272570559526064d20a1df5a3859a350dac9d6708113b787e8566a8db58cb6bc881d463ae2f4581865c8
7
- data.tar.gz: 62019c44c7e66c5d3858c9862d20276dbb876d024ca21d1d8691e3969944778c493fa3e988e0e22e2253c7515a6d453d2f11c794867941fa024017c9f28eeb02
6
+ metadata.gz: ead0edcbeda702bd605ea00562addfb65cb321e6797a2fb0e8c1fed640511d8bb5bb2b34a4acfa3bde12447bb0401d0975548661bc867cc7e5c1b5585db01425
7
+ data.tar.gz: c903baeebe4fbd700a58d9e193094648ccf0a3205e70fd78fb20a84cf09dfaee3f642ef45d78e4a50eb86d287b9d0974e8d33075528eef03702fe311175aa5e1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ## 2.1.3 (2022-06-12)
2
+
3
+ - Updated messages generator for Lockbox 1.0
4
+ - Fixed deprecation warning with Redis 4.6+
5
+
6
+ ## 2.1.2 (2022-02-09)
7
+
8
+ - Fixed external redirects with Rails 7
9
+
10
+ ## 2.1.1 (2021-12-13)
11
+
12
+ - Added experimental support for Active Record encryption
13
+
1
14
  ## 2.1.0 (2021-09-25)
2
15
 
3
16
  - Fixed mailer `default_url_options` not being applied to click links
data/README.md CHANGED
@@ -15,7 +15,7 @@ First-party email analytics for Rails
15
15
  Add this line to your application’s Gemfile:
16
16
 
17
17
  ```ruby
18
- gem 'ahoy_email'
18
+ gem "ahoy_email"
19
19
  ```
20
20
 
21
21
  ## Getting Started
@@ -28,17 +28,24 @@ There are three main features, which can be used independently:
28
28
 
29
29
  ## Message History
30
30
 
31
- To encrypt email addresses, install [Lockbox](https://github.com/ankane/lockbox) and [Blind Index](https://github.com/ankane/blind_index) and run:
31
+ To encrypt email addresses with Lockbox, install [Lockbox](https://github.com/ankane/lockbox) and [Blind Index](https://github.com/ankane/blind_index) and run:
32
32
 
33
33
  ```sh
34
- rails generate ahoy:messages
34
+ rails generate ahoy:messages --encryption=lockbox
35
+ rails db:migrate
36
+ ```
37
+
38
+ To use Active Record encryption (Rails 7+, experimental), run:
39
+
40
+ ```sh
41
+ rails generate ahoy:messages --encryption=activerecord
35
42
  rails db:migrate
36
43
  ```
37
44
 
38
45
  If you prefer not to encrypt data, run:
39
46
 
40
47
  ```sh
41
- rails generate ahoy:messages --unencrypted
48
+ rails generate ahoy:messages --encryption=none
42
49
  rails db:migrate
43
50
  ```
44
51
 
@@ -157,7 +164,7 @@ Ahoy::Message.where("created_at < ?", 1.year.ago).in_batches.delete_all
157
164
  Delete data for a specific user with:
158
165
 
159
166
  ```ruby
160
- Ahoy::Message.where(user_id: 1).in_batches.delete_all
167
+ Ahoy::Message.where(user_id: 1, user_type: "User").in_batches.delete_all
161
168
  ```
162
169
 
163
170
  ## UTM Tagging
@@ -223,7 +230,7 @@ AhoyEmail.api = true
223
230
  Add this line to your application’s Gemfile:
224
231
 
225
232
  ```ruby
226
- gem 'redis'
233
+ gem "redis"
227
234
  ```
228
235
 
229
236
  And create `config/initializers/ahoy_email.rb` with:
@@ -25,6 +25,9 @@ module Ahoy
25
25
  expected_signature = AhoyEmail::Utils.signature(token: token, campaign: campaign, url: url)
26
26
  end
27
27
 
28
+ redirect_options = {}
29
+ redirect_options[:allow_other_host] = true if ActionPack::VERSION::MAJOR >= 7
30
+
28
31
  if ActiveSupport::SecurityUtils.secure_compare(signature, expected_signature)
29
32
  data = {}
30
33
  data[:campaign] = campaign if campaign
@@ -33,10 +36,10 @@ module Ahoy
33
36
  data[:controller] = self
34
37
  AhoyEmail::Utils.publish(:click, data)
35
38
 
36
- redirect_to url
39
+ redirect_to url, **redirect_options
37
40
  else
38
41
  if AhoyEmail.invalid_redirect_url
39
- redirect_to AhoyEmail.invalid_redirect_url
42
+ redirect_to AhoyEmail.invalid_redirect_url, **redirect_options
40
43
  else
41
44
  render plain: "Link expired", status: :not_found
42
45
  end
@@ -9,17 +9,17 @@ module AhoyEmail
9
9
 
10
10
  def track_send(event)
11
11
  campaign_prefix = campaign_key(event[:campaign])
12
- redis.pipelined do
13
- redis.incr("#{campaign_prefix}:sends")
14
- redis.sadd(campaigns_key, event[:campaign])
12
+ pipelined do |pipeline|
13
+ pipeline.incr("#{campaign_prefix}:sends")
14
+ pipeline.sadd(campaigns_key, event[:campaign])
15
15
  end
16
16
  end
17
17
 
18
18
  def track_click(event)
19
19
  campaign_prefix = campaign_key(event[:campaign])
20
- redis.pipelined do
21
- redis.incr("#{campaign_prefix}:clicks")
22
- redis.pfadd("#{campaign_prefix}:unique_clicks", event[:token])
20
+ pipelined do |pipeline|
21
+ pipeline.incr("#{campaign_prefix}:clicks")
22
+ pipeline.pfadd("#{campaign_prefix}:unique_clicks", event[:token])
23
23
  end
24
24
  end
25
25
 
@@ -62,10 +62,10 @@ module AhoyEmail
62
62
  unique_clicks = nil
63
63
 
64
64
  campaign_prefix = campaign_key(campaign)
65
- redis.pipelined do
66
- sends = redis.get("#{campaign_prefix}:sends")
67
- clicks = redis.get("#{campaign_prefix}:clicks")
68
- unique_clicks = redis.pfcount("#{campaign_prefix}:unique_clicks")
65
+ pipelined do |pipeline|
66
+ sends = pipeline.get("#{campaign_prefix}:sends")
67
+ clicks = pipeline.get("#{campaign_prefix}:clicks")
68
+ unique_clicks = pipeline.pfcount("#{campaign_prefix}:unique_clicks")
69
69
  end
70
70
 
71
71
  {
@@ -75,5 +75,17 @@ module AhoyEmail
75
75
  ctr: 100 * unique_clicks.value / sends.value.to_f
76
76
  }
77
77
  end
78
+
79
+ def pipelined
80
+ if Redis::VERSION.to_f >= 4.6
81
+ redis.pipelined do |pipeline|
82
+ yield pipeline
83
+ end
84
+ else
85
+ redis.pipelined do
86
+ yield redis
87
+ end
88
+ end
89
+ end
78
90
  end
79
91
  end
@@ -1,3 +1,3 @@
1
1
  module AhoyEmail
2
- VERSION = "2.1.0"
2
+ VERSION = "2.1.3"
3
3
  end
@@ -7,15 +7,21 @@ module Ahoy
7
7
  include ActiveRecord::Generators::Migration
8
8
  source_root File.join(__dir__, "templates")
9
9
 
10
+ class_option :encryption, type: :string
11
+ # deprecated
10
12
  class_option :unencrypted, type: :boolean
11
13
 
12
14
  def copy_migration
15
+ encryption # ensure valid
13
16
  migration_template "migration.rb", "db/migrate/create_ahoy_messages.rb", migration_version: migration_version
14
17
  end
15
18
 
16
19
  def copy_template
17
- if encrypted?
18
- template "model_encrypted.rb", "app/models/ahoy/message.rb"
20
+ case encryption
21
+ when "lockbox"
22
+ template "model_lockbox.rb", "app/models/ahoy/message.rb", lockbox_method: lockbox_method
23
+ when "activerecord"
24
+ template "model_activerecord.rb", "app/models/ahoy/message.rb"
19
25
  end
20
26
  end
21
27
 
@@ -24,15 +30,38 @@ module Ahoy
24
30
  end
25
31
 
26
32
  def to_column
27
- if encrypted?
33
+ case encryption
34
+ when "lockbox"
28
35
  "t.text :to_ciphertext\n t.string :to_bidx, index: true"
29
36
  else
37
+ # TODO add limit: 510 for Active Record encryption + MySQL?
30
38
  "t.string :to, index: true"
31
39
  end
32
40
  end
33
41
 
34
- def encrypted?
35
- !options[:unencrypted]
42
+ # TODO remove default
43
+ def encryption
44
+ case options[:encryption]
45
+ when "lockbox", "activerecord", "none"
46
+ options[:encryption]
47
+ when nil
48
+ if options[:unencrypted]
49
+ # TODO deprecation warning
50
+ "none"
51
+ else
52
+ "lockbox"
53
+ end
54
+ else
55
+ abort "Error: encryption must be lockbox, activerecord, or none"
56
+ end
57
+ end
58
+
59
+ def lockbox_method
60
+ if defined?(Lockbox::VERSION) && Lockbox::VERSION.to_i < 1
61
+ "encrypts"
62
+ else
63
+ "has_encrypted"
64
+ end
36
65
  end
37
66
  end
38
67
  end
@@ -6,13 +6,41 @@ module Ahoy
6
6
  class MongoidGenerator < Rails::Generators::Base
7
7
  source_root File.join(__dir__, "templates")
8
8
 
9
+ class_option :encryption, type: :string
10
+ # deprecated
9
11
  class_option :unencrypted, type: :boolean
10
12
 
11
13
  def copy_templates
12
- if options[:unencrypted]
14
+ case encryption
15
+ when "lockbox"
16
+ template "mongoid_lockbox.rb", "app/models/ahoy/message.rb", lockbox_method: lockbox_method
17
+ else
13
18
  template "mongoid.rb", "app/models/ahoy/message.rb"
19
+ end
20
+ end
21
+
22
+ # TODO remove default
23
+ def encryption
24
+ case options[:encryption]
25
+ when "lockbox", "none"
26
+ options[:encryption]
27
+ when nil
28
+ if options[:unencrypted]
29
+ # TODO deprecation warning
30
+ "none"
31
+ else
32
+ "lockbox"
33
+ end
34
+ else
35
+ abort "Error: encryption must be lockbox or none"
36
+ end
37
+ end
38
+
39
+ def lockbox_method
40
+ if defined?(Lockbox::VERSION) && Lockbox::VERSION.to_i < 1
41
+ "encrypts"
14
42
  else
15
- template "mongoid_encrypted.rb", "app/models/ahoy/message.rb"
43
+ "has_encrypted"
16
44
  end
17
45
  end
18
46
  end
@@ -0,0 +1,7 @@
1
+ class Ahoy::Message < ActiveRecord::Base
2
+ self.table_name = "ahoy_messages"
3
+
4
+ belongs_to :user, polymorphic: true, optional: true
5
+
6
+ encrypts :to, deterministic: true
7
+ end
@@ -3,6 +3,6 @@ class Ahoy::Message < ActiveRecord::Base
3
3
 
4
4
  belongs_to :user, polymorphic: true, optional: true
5
5
 
6
- encrypts :to
6
+ <%= lockbox_method %> :to
7
7
  blind_index :to
8
8
  end
@@ -11,6 +11,6 @@ class Ahoy::Message
11
11
 
12
12
  index({to_bidx: 1})
13
13
 
14
- encrypts :to
14
+ <%= lockbox_method %> :to
15
15
  blind_index :to
16
16
  end
@@ -3,6 +3,8 @@ require "rails/generators"
3
3
  module Ahoy
4
4
  module Generators
5
5
  class MessagesGenerator < Rails::Generators::Base
6
+ class_option :encryption, type: :string
7
+ # deprecated
6
8
  class_option :unencrypted, type: :boolean
7
9
 
8
10
  def copy_templates
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_email
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-25 00:00:00.000000000 Z
11
+ date: 2022-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -99,9 +99,10 @@ files:
99
99
  - lib/generators/ahoy/messages/activerecord_generator.rb
100
100
  - lib/generators/ahoy/messages/mongoid_generator.rb
101
101
  - lib/generators/ahoy/messages/templates/migration.rb.tt
102
- - lib/generators/ahoy/messages/templates/model_encrypted.rb.tt
102
+ - lib/generators/ahoy/messages/templates/model_activerecord.rb.tt
103
+ - lib/generators/ahoy/messages/templates/model_lockbox.rb.tt
103
104
  - lib/generators/ahoy/messages/templates/mongoid.rb.tt
104
- - lib/generators/ahoy/messages/templates/mongoid_encrypted.rb.tt
105
+ - lib/generators/ahoy/messages/templates/mongoid_lockbox.rb.tt
105
106
  - lib/generators/ahoy/messages_generator.rb
106
107
  homepage: https://github.com/ankane/ahoy_email
107
108
  licenses:
@@ -122,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
123
  - !ruby/object:Gem::Version
123
124
  version: '0'
124
125
  requirements: []
125
- rubygems_version: 3.2.22
126
+ rubygems_version: 3.3.7
126
127
  signing_key:
127
128
  specification_version: 4
128
129
  summary: First-party email analytics for Rails