authtrail 0.2.1 → 0.4.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: 6ca58a6ac201b761a2cf30bed995135a44690ac7616770f9f1d2e74c45e23080
4
- data.tar.gz: 3ab3c476d2b75e1697a0a1e08cdc6e0356c07e266b1839c74eea1c1c4d818023
3
+ metadata.gz: fc8ae231bde9d10834ea6a7fa2fb0cd50a12e351ba2296abb15b743975fad197
4
+ data.tar.gz: c52435deca659cd45a8ed647daccaf8b19e9d7d92374db06be69c63cbcc6b1e3
5
5
  SHA512:
6
- metadata.gz: b7a769b8963f67a9cc0d37e194dd1e9b936271cfbc7c88ee0f1fe72252926fc6184c01bd9abad0420231507bc99e54fc22b85916c9a0cb3cc1611c402e3436f3
7
- data.tar.gz: 5cad0685a4773c31ef10f78380c9e64b4ca56828f9ba9eae8b4471a1b7cdd5d827b6f33c27a4963926003b199bbffad3971c98269e87c7cb850db33ad342a352
6
+ metadata.gz: 8531404800e70b37e0f6bca1fd79f690bfe36434efe768c926fa7248f1f50d803de16aa3324ecaa656c142940e69de35f80d2c5f4699f5408fbd92f41e5c24b0
7
+ data.tar.gz: bd4daf16b7ad615477cdbf0592f45d789fa7b6b0ba759c417f6e4e89888e2b4014dae6a2b48333a9863b6b1b0670082f9b9808da327dc790f2e0f173d6d63714
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 0.4.0 (2021-08-13)
2
+
3
+ - Disabled geocoding by default
4
+ - Made the `geocoder` gem an optional dependency
5
+ - Added `country_code` to geocoding
6
+
7
+ ## 0.3.1 (2021-03-03)
8
+
9
+ - Added `--lockbox` option to install generator
10
+
11
+ ## 0.3.0 (2021-03-01)
12
+
13
+ - Disabled geocoding by default for new installations
14
+ - Raise an exception instead of logging when auditing fails
15
+ - Removed support for Rails < 5.2 and Ruby < 2.6
16
+
17
+ ## 0.2.2 (2020-11-21)
18
+
19
+ - Added `transform_method` option
20
+
1
21
  ## 0.2.1 (2020-08-17)
2
22
 
3
23
  - Added `job_queue` option
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2020 Andrew Kane
1
+ Copyright (c) 2017-2021 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  Track Devise login activity
4
4
 
5
+ **AuthTrail 0.4.0 was recently released** - see [how to upgrade](#upgrading)
6
+
5
7
  :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
6
8
 
7
- [![Build Status](https://travis-ci.org/ankane/authtrail.svg?branch=master)](https://travis-ci.org/ankane/authtrail)
9
+ [![Build Status](https://github.com/ankane/authtrail/workflows/build/badge.svg?branch=master)](https://github.com/ankane/authtrail/actions)
8
10
 
9
11
  ## Installation
10
12
 
@@ -14,13 +16,22 @@ Add this line to your application’s Gemfile:
14
16
  gem 'authtrail'
15
17
  ```
16
18
 
17
- And run:
19
+ To encrypt email and IP addresses, install [Lockbox](https://github.com/ankane/lockbox) and [Blind Index](https://github.com/ankane/blind_index) and run:
20
+
21
+ ```sh
22
+ rails generate authtrail:install --lockbox
23
+ rails db:migrate
24
+ ```
25
+
26
+ If you prefer not to encrypt data, run:
18
27
 
19
28
  ```sh
20
29
  rails generate authtrail:install
21
30
  rails db:migrate
22
31
  ```
23
32
 
33
+ To enable geocoding, see the [Geocoding section](#geocoding).
34
+
24
35
  ## How It Works
25
36
 
26
37
  A `LoginActivity` record is created every time a user tries to login. You can then use this information to detect suspicious behavior. Data includes:
@@ -42,15 +53,31 @@ A `LoginActivity` record is created every time a user tries to login. You can th
42
53
  Exclude certain attempts from tracking - useful if you run acceptance tests
43
54
 
44
55
  ```ruby
45
- AuthTrail.exclude_method = lambda do |info|
46
- info[:identity] == "capybara@example.org"
56
+ AuthTrail.exclude_method = lambda do |data|
57
+ data[:identity] == "capybara@example.org"
58
+ end
59
+ ```
60
+
61
+ Add or modify data - also add new fields to the `login_activities` table if needed
62
+
63
+ ```ruby
64
+ AuthTrail.transform_method = lambda do |data, request|
65
+ data[:request_id] = request.request_id
66
+ end
67
+ ```
68
+
69
+ Store the user on failed attempts
70
+
71
+ ```ruby
72
+ AuthTrail.transform_method = lambda do |data, request|
73
+ data[:user] ||= User.find_by(email: data[:identity])
47
74
  end
48
75
  ```
49
76
 
50
77
  Write data somewhere other than the `login_activities` table
51
78
 
52
79
  ```ruby
53
- AuthTrail.track_method = lambda do |info|
80
+ AuthTrail.track_method = lambda do |data|
54
81
  # code
55
82
  end
56
83
  ```
@@ -79,50 +106,82 @@ The `LoginActivity` model uses a [polymorphic association](https://guides.rubyon
79
106
 
80
107
  ## Geocoding
81
108
 
82
- IP geocoding is performed in a background job so it doesn’t slow down web requests. You can disable it entirely with:
109
+ AuthTrail uses [Geocoder](https://github.com/alexreisner/geocoder) for geocoding. We recommend configuring [local geocoding](#local-geocoding) or [load balancer geocoding](#load-balancer-geocoding) so IP addresses are not sent to a 3rd party service. If you do use a 3rd party service and adhere to GDPR, be sure to add it to your subprocessor list.
110
+
111
+ To enable geocoding, add this line to your application’s Gemfile:
83
112
 
84
113
  ```ruby
85
- AuthTrail.geocode = false
114
+ gem 'geocoder'
86
115
  ```
87
116
 
88
- Set job queue for geocoding
117
+ And update `config/initializers/authtrail.rb`:
89
118
 
90
119
  ```ruby
91
- AuthTrail.job_queue = :low_priority
120
+ AuthTrail.geocode = true
92
121
  ```
93
122
 
94
- ### Geocoding Performance
123
+ Geocoding is performed in a background job so it doesn’t slow down web requests. Set the job queue with:
124
+
125
+ ```ruby
126
+ AuthTrail.job_queue = :low_priority
127
+ ```
95
128
 
96
- To avoid calls to a remote API, download the [GeoLite2 City database](https://dev.maxmind.com/geoip/geoip2/geolite2/) and configure Geocoder to use it.
129
+ ### Local Geocoding
97
130
 
98
- Add this line to your application’s Gemfile:
131
+ For privacy and performance, we recommend geocoding locally. Add this line to your application’s Gemfile:
99
132
 
100
133
  ```ruby
101
134
  gem 'maxminddb'
102
135
  ```
103
136
 
104
- And create an initializer at `config/initializers/geocoder.rb` with:
137
+ For city-level geocoding, download the [GeoLite2 City database](https://dev.maxmind.com/geoip/geoip2/geolite2/) and create `config/initializers/geocoder.rb` with:
105
138
 
106
139
  ```ruby
107
140
  Geocoder.configure(
108
141
  ip_lookup: :geoip2,
109
142
  geoip2: {
110
- file: Rails.root.join("lib", "GeoLite2-City.mmdb")
143
+ file: "path/to/GeoLite2-City.mmdb"
144
+ }
145
+ )
146
+ ```
147
+
148
+ For country-level geocoding, install the `geoip-database` package. It’s preinstalled on Heroku. For Ubuntu, use:
149
+
150
+ ```sh
151
+ sudo apt-get install geoip-database
152
+ ```
153
+
154
+ And create `config/initializers/geocoder.rb` with:
155
+
156
+ ```ruby
157
+ Geocoder.configure(
158
+ ip_lookup: :maxmind_local,
159
+ maxmind_local: {
160
+ file: "/usr/share/GeoIP/GeoIP.dat",
161
+ package: :country
111
162
  }
112
163
  )
113
164
  ```
114
165
 
115
- ## Data Protection
166
+ ### Load Balancer Geocoding
116
167
 
117
- Protect the privacy of your users by encrypting fields that contain personal data, such as `identity` and `ip`. [Lockbox](https://github.com/ankane/lockbox) is great for this. Use [Blind Index](https://github.com/ankane/blind_index) so you can still query the fields.
168
+ Some load balancers can add geocoding information to request headers.
169
+
170
+ - [nginx](https://nginx.org/en/docs/http/ngx_http_geoip_module.html)
171
+ - [Google Cloud](https://cloud.google.com/load-balancing/docs/custom-headers)
172
+ - [Cloudflare](https://support.cloudflare.com/hc/en-us/articles/200168236-Configuring-Cloudflare-IP-Geolocation)
118
173
 
119
174
  ```ruby
120
- class LoginActivity < ApplicationRecord
121
- encrypts :identity, :ip
122
- blind_index :identity, :ip
175
+ AuthTrail.geocode = false
176
+ AuthTrail.transform_method = lambda do |data, request|
177
+ data[:country] = request.headers["<country-header>"]
178
+ data[:region] = request.headers["<region-header>"]
179
+ data[:city] = request.headers["<city-header>"]
123
180
  end
124
181
  ```
125
182
 
183
+ Check out [this example](https://github.com/ankane/authtrail/issues/40)
184
+
126
185
  ## Other Notes
127
186
 
128
187
  We recommend using this in addition to Devise’s `Lockable` module and [Rack::Attack](https://github.com/kickstarter/rack-attack).
@@ -131,6 +190,18 @@ Check out [Hardening Devise](https://ankane.org/hardening-devise) and [Secure Ra
131
190
 
132
191
  ## Upgrading
133
192
 
193
+ ### 0.4.0
194
+
195
+ There are two notable changes to geocoding:
196
+
197
+ 1. Geocoding is now disabled by default (this was already the case for new installations with 0.3.0+). Check out the instructions for [how to enable it](#geocoding) (you may need to create `config/initializers/authtrail.rb`).
198
+
199
+ 2. The `geocoder` gem is now an optional dependency. To use geocoding, add it to your Gemfile:
200
+
201
+ ```ruby
202
+ gem 'geocoder'
203
+ ```
204
+
134
205
  ### 0.2.0
135
206
 
136
207
  To store latitude and longitude, create a migration with:
@@ -8,6 +8,9 @@ module AuthTrail
8
8
  result =
9
9
  begin
10
10
  Geocoder.search(login_activity.ip).first
11
+ rescue NameError
12
+ # geocoder gem not installed
13
+ raise
11
14
  rescue => e
12
15
  Rails.logger.info "Geocode failed: #{e.message}"
13
16
  nil
@@ -18,6 +21,7 @@ module AuthTrail
18
21
  city: result.try(:city),
19
22
  region: result.try(:state),
20
23
  country: result.try(:country),
24
+ country_code: result.try(:country_code),
21
25
  latitude: result.try(:latitude),
22
26
  longitude: result.try(:longitude)
23
27
  }
@@ -2,34 +2,29 @@ module AuthTrail
2
2
  module Manager
3
3
  class << self
4
4
  def after_set_user(user, auth, opts)
5
- # do not raise an exception for tracking
6
- AuthTrail.safely do
7
- request = ActionDispatch::Request.new(auth.env)
5
+ request = ActionDispatch::Request.new(auth.env)
8
6
 
9
- AuthTrail.track(
10
- strategy: detect_strategy(auth),
11
- scope: opts[:scope].to_s,
12
- identity: AuthTrail.identity_method.call(request, opts, user),
13
- success: true,
14
- request: request,
15
- user: user
16
- )
17
- end
7
+ AuthTrail.track(
8
+ strategy: detect_strategy(auth),
9
+ scope: opts[:scope].to_s,
10
+ identity: AuthTrail.identity_method.call(request, opts, user),
11
+ success: true,
12
+ request: request,
13
+ user: user
14
+ )
18
15
  end
19
16
 
20
17
  def before_failure(env, opts)
21
- AuthTrail.safely do
22
- request = ActionDispatch::Request.new(env)
18
+ request = ActionDispatch::Request.new(env)
23
19
 
24
- AuthTrail.track(
25
- strategy: detect_strategy(env["warden"]),
26
- scope: opts[:scope].to_s,
27
- identity: AuthTrail.identity_method.call(request, opts, nil),
28
- success: false,
29
- request: request,
30
- failure_reason: opts[:message].to_s
31
- )
32
- end
20
+ AuthTrail.track(
21
+ strategy: detect_strategy(env["warden"]),
22
+ scope: opts[:scope].to_s,
23
+ identity: AuthTrail.identity_method.call(request, opts, nil),
24
+ success: false,
25
+ request: request,
26
+ failure_reason: opts[:message].to_s
27
+ )
33
28
  end
34
29
 
35
30
  private
@@ -1,3 +1,3 @@
1
1
  module AuthTrail
2
- VERSION = "0.2.1"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/authtrail.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  # dependencies
2
- require "geocoder"
3
2
  require "warden"
4
3
 
5
4
  # modules
@@ -9,9 +8,9 @@ require "auth_trail/version"
9
8
 
10
9
  module AuthTrail
11
10
  class << self
12
- attr_accessor :exclude_method, :geocode, :track_method, :identity_method, :job_queue
11
+ attr_accessor :exclude_method, :geocode, :track_method, :identity_method, :job_queue, :transform_method
13
12
  end
14
- self.geocode = true
13
+ self.geocode = false
15
14
  self.identity_method = lambda do |request, opts, user|
16
15
  if user
17
16
  user.try(:email)
@@ -22,7 +21,7 @@ module AuthTrail
22
21
  end
23
22
 
24
23
  def self.track(strategy:, scope:, identity:, success:, request:, user: nil, failure_reason: nil)
25
- info = {
24
+ data = {
26
25
  strategy: strategy,
27
26
  scope: scope,
28
27
  identity: identity,
@@ -35,18 +34,22 @@ module AuthTrail
35
34
  }
36
35
 
37
36
  if request.params[:controller]
38
- info[:context] = "#{request.params[:controller]}##{request.params[:action]}"
37
+ data[:context] = "#{request.params[:controller]}##{request.params[:action]}"
39
38
  end
40
39
 
40
+ # add request data before exclude_method since exclude_method doesn't have access to request
41
+ # could also add 2nd argument to exclude_method when arity > 1
42
+ AuthTrail.transform_method.call(data, request) if AuthTrail.transform_method
43
+
41
44
  # if exclude_method throws an exception, default to not excluding
42
- exclude = AuthTrail.exclude_method && AuthTrail.safely(default: false) { AuthTrail.exclude_method.call(info) }
45
+ exclude = AuthTrail.exclude_method && AuthTrail.safely(default: false) { AuthTrail.exclude_method.call(data) }
43
46
 
44
47
  unless exclude
45
48
  if AuthTrail.track_method
46
- AuthTrail.track_method.call(info)
49
+ AuthTrail.track_method.call(data)
47
50
  else
48
51
  login_activity = LoginActivity.new
49
- info.each do |k, v|
52
+ data.each do |k, v|
50
53
  login_activity.try("#{k}=", v)
51
54
  end
52
55
  login_activity.save!
@@ -6,17 +6,47 @@ module Authtrail
6
6
  include ActiveRecord::Generators::Migration
7
7
  source_root File.join(__dir__, "templates")
8
8
 
9
+ class_option :lockbox, type: :boolean
10
+
9
11
  def copy_migration
10
12
  migration_template "login_activities_migration.rb", "db/migrate/create_login_activities.rb", migration_version: migration_version
11
13
  end
12
14
 
15
+ def copy_templates
16
+ template "initializer.rb", "config/initializers/authtrail.rb"
17
+ end
18
+
13
19
  def generate_model
14
- template "login_activity_model.rb", "app/models/login_activity.rb"
20
+ if lockbox?
21
+ template "model_lockbox.rb", "app/models/login_activity.rb"
22
+ else
23
+ template "model.rb", "app/models/login_activity.rb"
24
+ end
15
25
  end
16
26
 
17
27
  def migration_version
18
28
  "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
19
29
  end
30
+
31
+ def identity_column
32
+ if lockbox?
33
+ "t.text :identity_ciphertext\n t.string :identity_bidx, index: true"
34
+ else
35
+ "t.string :identity, index: true"
36
+ end
37
+ end
38
+
39
+ def ip_column
40
+ if lockbox?
41
+ "t.text :ip_ciphertext\n t.string :ip_bidx, index: true"
42
+ else
43
+ "t.string :ip, index: true"
44
+ end
45
+ end
46
+
47
+ def lockbox?
48
+ options[:lockbox]
49
+ end
20
50
  end
21
51
  end
22
52
  end
@@ -0,0 +1,14 @@
1
+ # set to true for geocoding (and add the geocoder gem to your Gemfile)
2
+ # we recommend configuring local geocoding as well
3
+ # see https://github.com/ankane/authtrail#geocoding
4
+ AuthTrail.geocode = false
5
+
6
+ # add or modify data
7
+ # AuthTrail.transform_method = lambda do |data, request|
8
+ # data[:request_id] = request.request_id
9
+ # end
10
+
11
+ # exclude certain attempts from tracking
12
+ # AuthTrail.exclude_method = lambda do |data|
13
+ # data[:identity] == "capybara@example.org"
14
+ # end
@@ -3,12 +3,12 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
3
3
  create_table :login_activities do |t|
4
4
  t.string :scope
5
5
  t.string :strategy
6
- t.string :identity
6
+ <%= identity_column %>
7
7
  t.boolean :success
8
8
  t.string :failure_reason
9
9
  t.references :user, polymorphic: true
10
10
  t.string :context
11
- t.string :ip
11
+ <%= ip_column %>
12
12
  t.text :user_agent
13
13
  t.text :referrer
14
14
  t.string :city
@@ -18,8 +18,5 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
18
18
  t.float :longitude
19
19
  t.datetime :created_at
20
20
  end
21
-
22
- add_index :login_activities, :identity
23
- add_index :login_activities, :ip
24
21
  end
25
22
  end
@@ -0,0 +1,14 @@
1
+ class LoginActivity < ApplicationRecord
2
+ belongs_to :user, polymorphic: true, optional: true
3
+
4
+ encrypts :identity, :ip
5
+ blind_index :identity, :ip
6
+
7
+ before_save :reduce_precision
8
+
9
+ # reduce precision to city level to protect IP
10
+ def reduce_precision
11
+ self.latitude = latitude&.round(1) if try(:latitude_changed?)
12
+ self.longitude = longitude&.round(1) if try(:longitude_changed?)
13
+ end
14
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authtrail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-17 00:00:00.000000000 Z
11
+ date: 2021-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '5'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '5'
33
+ version: '5.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '5'
40
+ version: '5.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: warden
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,120 +52,8 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: geocoder
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: bundler
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: minitest
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '5'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '5'
111
- - !ruby/object:Gem::Dependency
112
- name: combustion
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: rails
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: sqlite3
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: devise
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
- description:
168
- email: andrew@chartkick.com
55
+ description:
56
+ email: andrew@ankane.org
169
57
  executables: []
170
58
  extensions: []
171
59
  extra_rdoc_files: []
@@ -179,13 +67,15 @@ files:
179
67
  - lib/auth_trail/version.rb
180
68
  - lib/authtrail.rb
181
69
  - lib/generators/authtrail/install_generator.rb
70
+ - lib/generators/authtrail/templates/initializer.rb.tt
182
71
  - lib/generators/authtrail/templates/login_activities_migration.rb.tt
183
- - lib/generators/authtrail/templates/login_activity_model.rb.tt
72
+ - lib/generators/authtrail/templates/model.rb.tt
73
+ - lib/generators/authtrail/templates/model_lockbox.rb.tt
184
74
  homepage: https://github.com/ankane/authtrail
185
75
  licenses:
186
76
  - MIT
187
77
  metadata: {}
188
- post_install_message:
78
+ post_install_message:
189
79
  rdoc_options: []
190
80
  require_paths:
191
81
  - lib
@@ -193,15 +83,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
193
83
  requirements:
194
84
  - - ">="
195
85
  - !ruby/object:Gem::Version
196
- version: '2.4'
86
+ version: '2.6'
197
87
  required_rubygems_version: !ruby/object:Gem::Requirement
198
88
  requirements:
199
89
  - - ">="
200
90
  - !ruby/object:Gem::Version
201
91
  version: '0'
202
92
  requirements: []
203
- rubygems_version: 3.1.2
204
- signing_key:
93
+ rubygems_version: 3.2.22
94
+ signing_key:
205
95
  specification_version: 4
206
96
  summary: Track Devise login activity
207
97
  test_files: []