devise-authy 1.11.0 → 2.2.1
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 +4 -4
- data/.gitignore +5 -4
- data/.rspec +1 -0
- data/.travis.yml +7 -8
- data/Appraisals +21 -0
- data/CHANGELOG.md +49 -0
- data/Gemfile +0 -23
- data/README.md +43 -14
- data/app/controllers/devise/devise_authy_controller.rb +67 -22
- data/app/controllers/devise_authy/passwords_controller.rb +18 -0
- data/app/views/devise/verify_authy.html.erb +3 -2
- data/app/views/devise/verify_authy.html.haml +3 -2
- data/app/views/devise/verify_authy_installation.html.erb +11 -3
- data/app/views/devise/verify_authy_installation.html.haml +9 -1
- data/config.ru +9 -0
- data/config/locales/en.yml +3 -0
- data/devise-authy.gemspec +20 -10
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/rails_5_2.gemfile +15 -0
- data/gemfiles/rails_6.gemfile +15 -0
- data/lib/devise-authy.rb +4 -3
- data/lib/devise-authy/controllers/helpers.rb +5 -5
- data/lib/devise-authy/models/authy_authenticatable.rb +1 -1
- data/lib/devise-authy/version.rb +2 -2
- data/lib/generators/active_record/devise_authy_generator.rb +3 -3
- data/lib/generators/devise_authy/devise_authy_generator.rb +4 -2
- data/lib/generators/devise_authy/install_generator.rb +9 -5
- metadata +160 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9157eb5b102b0297c975ea71d190f500e0bf6dc5831717df0ca5695b9f0af13e
|
|
4
|
+
data.tar.gz: 7582bfb6b18310dd7697a808460ac87282d1c2e3fc9fd09838c431d69315d655
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 36cc430cf270f535c3068c15668a398bbc9a297d345bb0c659db49ef5fb9febb43761abcf118c340476797a8c7150de37cb6ddcd0caf14b408cdecb94ab856f6
|
|
7
|
+
data.tar.gz: 856434e4038f931c25f84ddac5281f0b5f762e4a6d9d27a355362822342c255bea58ee6b087a52d912802b654436ef7505efc6a310375cafb67bdfafa5d800e1
|
data/.gitignore
CHANGED
|
@@ -31,14 +31,15 @@ build/
|
|
|
31
31
|
Gemfile.lock
|
|
32
32
|
.ruby-version
|
|
33
33
|
.ruby-gemset
|
|
34
|
+
gemfiles/*.lock
|
|
34
35
|
|
|
35
36
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
36
37
|
.rvmrc
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
spec/rails-app/log
|
|
41
|
-
*.sqlite3DS_Store
|
|
39
|
+
**/*.sqlite
|
|
40
|
+
**/*.log
|
|
42
41
|
|
|
43
42
|
initializers/authy.rb
|
|
44
43
|
.byebug_history
|
|
44
|
+
|
|
45
|
+
.rspec_status
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
language: ruby
|
|
2
|
-
before_install:
|
|
3
|
-
- "find /home/travis/.rvm/rubies -wholename '*default/bundler-*.gemspec' -delete"
|
|
4
|
-
- rvm @global do gem uninstall bundler -a -x
|
|
5
|
-
- rvm @global do yes | gem install bundler -v '< 2.0.0'
|
|
6
|
-
- cd spec/rails-app && BUNDLE_GEMFILE=$TRAVIS_BUILD_DIR/spec/rails-app/Gemfile bundle install && cd ../..
|
|
7
2
|
script: bundle exec rspec
|
|
8
3
|
rvm:
|
|
4
|
+
- 2.7
|
|
9
5
|
- 2.6
|
|
10
6
|
- 2.5
|
|
11
7
|
- 2.4
|
|
12
|
-
- 2.3
|
|
13
|
-
- 2.2
|
|
14
8
|
- ruby-head
|
|
9
|
+
gemfile:
|
|
10
|
+
- gemfiles/rails_5_2.gemfile
|
|
11
|
+
- gemfiles/rails_6.gemfile
|
|
15
12
|
matrix:
|
|
16
13
|
allow_failures:
|
|
17
14
|
- rvm: ruby-head
|
|
18
|
-
|
|
15
|
+
exclude:
|
|
16
|
+
- rvm: 2.4
|
|
17
|
+
gemfile: gemfiles/rails_6.gemfile
|
data/Appraisals
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
appraise "rails-5-2" do
|
|
2
|
+
gem "rails", "~> 5.2.0"
|
|
3
|
+
gem "sqlite3", "~> 1.3.13"
|
|
4
|
+
|
|
5
|
+
group :development, :test do
|
|
6
|
+
gem 'factory_girl_rails', :require => false
|
|
7
|
+
gem 'rspec-rails', "~>4.0.0.beta3", :require => false
|
|
8
|
+
gem 'database_cleaner', :require => false
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
appraise "rails-6" do
|
|
13
|
+
gem "rails", "~> 6.0.0"
|
|
14
|
+
gem "sqlite3", "~> 1.4"
|
|
15
|
+
|
|
16
|
+
group :development, :test do
|
|
17
|
+
gem 'factory_girl_rails', :require => false
|
|
18
|
+
gem 'rspec-rails', "~>4.0.0.beta3", :require => false
|
|
19
|
+
gem 'database_cleaner', :require => false
|
|
20
|
+
end
|
|
21
|
+
end if RUBY_VERSION.to_f >= 2.5
|
data/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,55 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
9
9
|
|
|
10
10
|
...
|
|
11
11
|
|
|
12
|
+
## [2.2.1] - 2020-10-13
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- If the app offers a QR code scan and user fails to verify authy installation, the QR code wasn't shown again. Fixed in (#149)
|
|
17
|
+
|
|
18
|
+
## [2.2.0] - 2020-06-04
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Don't delete user in Authy if another user has the same authy_id (#144)
|
|
23
|
+
|
|
24
|
+
## [2.1.0] - 2020-05-05
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Support for generic authenticator tokens (#141)
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Can remember device when enabling 2FA for the first time (#139)
|
|
33
|
+
|
|
34
|
+
## [2.0.0] - 2020-04-28
|
|
35
|
+
|
|
36
|
+
Releasing this as version 2 because there is a significant change in dependencies. Minimum version of Rails is now 5 and of Devise is now 4. Otherwise the gem should work as before.
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- HTTP Only flag to remember_device cookie (#116 thanks @agronv)
|
|
41
|
+
- Remembers device when user logs in with One Touch (#128 thanks @cplopez4)
|
|
42
|
+
- Autocomplete attributes for HTML form (#130)
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- Mocked API calls in test suite (#123)
|
|
47
|
+
- Full test suite refactor (#124)
|
|
48
|
+
- Increased required version for Devise and Rails (#125)
|
|
49
|
+
- Stopped calling `signed_in?` before it is needed (#126)
|
|
50
|
+
|
|
51
|
+
### Fixes
|
|
52
|
+
|
|
53
|
+
- Remembers user correctly when logging in with One Touch (#129)
|
|
54
|
+
|
|
55
|
+
## [1.11.1] - 2019-02-02
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
|
|
59
|
+
- Using the version before loading it broke everything. :facepalm:
|
|
60
|
+
|
|
12
61
|
## [1.11.0] - 2019-02-01
|
|
13
62
|
|
|
14
63
|
### Fixed
|
data/Gemfile
CHANGED
|
@@ -2,28 +2,5 @@ source 'https://rubygems.org'
|
|
|
2
2
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
|
-
group :test do
|
|
6
|
-
gem 'rails', '~> 4.2.7'
|
|
7
|
-
gem 'sqlite3'
|
|
8
|
-
|
|
9
|
-
# Use SCSS for stylesheets
|
|
10
|
-
gem 'sass-rails', '~> 5.0'
|
|
11
|
-
|
|
12
|
-
# Use Uglifier as compressor for JavaScript assets
|
|
13
|
-
gem 'uglifier', '>= 1.3.0'
|
|
14
|
-
|
|
15
|
-
# Use CoffeeScript for .coffee assets and views
|
|
16
|
-
gem 'coffee-rails', '~> 4.1.0'
|
|
17
|
-
|
|
18
|
-
# Use jquery as the JavaScript library
|
|
19
|
-
gem 'jquery-rails'
|
|
20
|
-
|
|
21
|
-
gem 'launchy'
|
|
22
|
-
gem 'rspec-rails'
|
|
23
|
-
gem 'database_cleaner'
|
|
24
|
-
gem 'capybara'
|
|
25
|
-
gem 'test-unit'
|
|
26
|
-
end
|
|
27
|
-
|
|
28
5
|
# bundle exec rake doc:rails generates the API under doc/api.
|
|
29
6
|
gem 'sdoc', '~> 0.4.0', group: :doc
|
data/README.md
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
# Authy Devise [](https://travis-ci.org/twilio/authy-devise)
|
|
2
2
|
|
|
3
|
-
This is a [Devise](https://github.com/plataformatec/devise) extension to add Two-Factor Authentication with Authy to your
|
|
3
|
+
This is a [Devise](https://github.com/plataformatec/devise) extension to add [Two-Factor Authentication with Authy](https://www.twilio.com/docs/authy) to your Rails application.
|
|
4
|
+
|
|
5
|
+
* [Pre-requisites](#pre-requisites)
|
|
6
|
+
* [Demo](#demo)
|
|
7
|
+
* [Getting started](#getting-started)
|
|
8
|
+
* [Configuring Models](#configuring-models)
|
|
9
|
+
* [With the generator](#with-the-generator)
|
|
10
|
+
* [Manually](#manually)
|
|
11
|
+
* [Final steps](#final-steps)
|
|
12
|
+
* [Custom Views](#custom-views)
|
|
13
|
+
* [Request a phone call](#request-a-phone-call)
|
|
14
|
+
* [Custom Redirect Paths (eg. using modules)](#custom-redirect-paths-eg-using-modules)
|
|
15
|
+
* [I18n](#i18n)
|
|
16
|
+
* [Session variables](#session-variables)
|
|
17
|
+
* [OneTouch support](#onetouch-support)
|
|
18
|
+
* [Generic authenticator token support](#generic-authenticator-token-support)
|
|
19
|
+
* [Rails 5 CSRF protection](#rails-5-csrf-protection)
|
|
20
|
+
* [Running Tests](#running-tests)
|
|
21
|
+
* [Copyright](#copyright)
|
|
4
22
|
|
|
5
23
|
## Pre-requisites
|
|
6
24
|
|
|
7
|
-
To use the Authy API you will need a Twilio Account, [sign up for a free account here](https://www.twilio.com/try-twilio).
|
|
25
|
+
To use the Authy API you will need a Twilio Account, [sign up for a free Twilio account here](https://www.twilio.com/try-twilio).
|
|
8
26
|
|
|
9
27
|
Create an [Authy Application in the Twilio console](https://www.twilio.com/console/authy/applications) and take note of the API key.
|
|
10
28
|
|
|
@@ -42,24 +60,28 @@ You can add devise_authy to your user model in two ways.
|
|
|
42
60
|
|
|
43
61
|
#### With the generator
|
|
44
62
|
|
|
45
|
-
|
|
63
|
+
Run the following command:
|
|
46
64
|
|
|
47
65
|
```bash
|
|
48
66
|
rails g devise_authy [MODEL_NAME]
|
|
49
67
|
```
|
|
50
68
|
|
|
69
|
+
To support account locking (recommended), you must add `:authy_lockable` to the `devise :authy_authenticatable, ...` configuration in your model as this is not yet supported by the generator.
|
|
70
|
+
|
|
51
71
|
#### Manually
|
|
52
72
|
|
|
53
|
-
Add `:authy_authenticatable` to the `devise` options in your Devise user model:
|
|
73
|
+
Add `:authy_authenticatable` and `:authy_lockable` to the `devise` options in your Devise user model:
|
|
54
74
|
|
|
55
75
|
```ruby
|
|
56
|
-
devise :authy_authenticatable, :database_authenticatable
|
|
76
|
+
devise :authy_authenticatable, :authy_lockable, :database_authenticatable, :lockable
|
|
57
77
|
```
|
|
58
78
|
|
|
79
|
+
(Note, `:authy_lockable` is optional but recommended. It should be used with Devise's own `:lockable` module).
|
|
80
|
+
|
|
59
81
|
Also add a new migration. For example, if you are adding to the `User` model, use this migration:
|
|
60
82
|
|
|
61
83
|
```ruby
|
|
62
|
-
class DeviseAuthyAddToUsers < ActiveRecord::Migration[
|
|
84
|
+
class DeviseAuthyAddToUsers < ActiveRecord::Migration[6.0]
|
|
63
85
|
def self.up
|
|
64
86
|
change_table :users do |t|
|
|
65
87
|
t.string :authy_id
|
|
@@ -177,6 +199,20 @@ To enable [Authy push authentication](https://www.twilio.com/authy/features/push
|
|
|
177
199
|
config.authy_enable_onetouch = true
|
|
178
200
|
```
|
|
179
201
|
|
|
202
|
+
## Generic authenticator token support
|
|
203
|
+
|
|
204
|
+
Authy supports other authenticator apps by providing a QR code that your users can scan.
|
|
205
|
+
|
|
206
|
+
> **To use this feature, you need to enable it in your [Twilio Console](https://www.twilio.com/console/authy/applications)**
|
|
207
|
+
|
|
208
|
+
Once you have enabled generic authenticator tokens, you can enable this in devise-authy by modifying the Devise config file `config/initializers/devise.rb` and adding the configuration:
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
config.authy_enable_qr_code = true
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
This will display a QR code on the verification screen (you still need to take a user's phone number and country code). If you have implemented your own views, the QR code URL is available on the verification page as `@authy_qr_code`.
|
|
215
|
+
|
|
180
216
|
## Rails 5 CSRF protection
|
|
181
217
|
|
|
182
218
|
In Rails 5 `protect_from_forgery` is no longer prepended to the `before_action` chain. If you call `authenticate_user` before `protect_from_forgery` your request will result in a "Can't verify CSRF token authenticity" error.
|
|
@@ -205,13 +241,6 @@ Now on the project root run the following commands:
|
|
|
205
241
|
$ bundle exec rspec spec/
|
|
206
242
|
```
|
|
207
243
|
|
|
208
|
-
## Backporting to Rails 3
|
|
209
|
-
|
|
210
|
-
While we are not currently supporting Rails 3, there's an active fork that maintains the backwards compatibility.
|
|
211
|
-
|
|
212
|
-
https://github.com/gcosta/authy-devise
|
|
213
|
-
|
|
214
244
|
## Copyright
|
|
215
245
|
|
|
216
|
-
Copyright (c) 2012-2020 Authy Inc. See LICENSE.txt for
|
|
217
|
-
further details.
|
|
246
|
+
Copyright (c) 2012-2020 Authy Inc. See LICENSE.txt for further details.
|
|
@@ -5,17 +5,25 @@ class Devise::DeviseAuthyController < DeviseController
|
|
|
5
5
|
prepend_before_action :find_resource_and_require_password_checked, :only => [
|
|
6
6
|
:GET_verify_authy, :POST_verify_authy, :GET_authy_onetouch_status
|
|
7
7
|
]
|
|
8
|
+
|
|
9
|
+
prepend_before_action :check_resource_has_authy_id, :only => [
|
|
10
|
+
:GET_verify_authy_installation, :POST_verify_authy_installation
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
prepend_before_action :check_resource_not_authy_enabled, :only => [
|
|
14
|
+
:GET_verify_authy_installation, :POST_verify_authy_installation
|
|
15
|
+
]
|
|
16
|
+
|
|
8
17
|
prepend_before_action :authenticate_scope!, :only => [
|
|
9
|
-
:GET_enable_authy, :POST_enable_authy,
|
|
10
|
-
:
|
|
11
|
-
:POST_disable_authy
|
|
18
|
+
:GET_enable_authy, :POST_enable_authy, :GET_verify_authy_installation,
|
|
19
|
+
:POST_verify_authy_installation, :POST_disable_authy
|
|
12
20
|
]
|
|
21
|
+
|
|
13
22
|
include Devise::Controllers::Helpers
|
|
14
23
|
|
|
15
24
|
def GET_verify_authy
|
|
16
|
-
@authy_id = @resource.authy_id
|
|
17
25
|
if resource_class.authy_enable_onetouch
|
|
18
|
-
approval_request = send_one_touch_request['approval_request']
|
|
26
|
+
approval_request = send_one_touch_request(@resource.authy_id)['approval_request']
|
|
19
27
|
@onetouch_uuid = approval_request['uuid'] if approval_request.present?
|
|
20
28
|
end
|
|
21
29
|
render :verify_authy
|
|
@@ -30,10 +38,8 @@ class Devise::DeviseAuthyController < DeviseController
|
|
|
30
38
|
})
|
|
31
39
|
|
|
32
40
|
if token.ok?
|
|
33
|
-
remember_device if params[:remember_device].to_i == 1
|
|
34
|
-
|
|
35
|
-
@resource.remember_me = true
|
|
36
|
-
end
|
|
41
|
+
remember_device(@resource.id) if params[:remember_device].to_i == 1
|
|
42
|
+
remember_user
|
|
37
43
|
record_authy_authentication
|
|
38
44
|
respond_with resource, :location => after_sign_in_path_for(@resource)
|
|
39
45
|
else
|
|
@@ -61,13 +67,11 @@ class Devise::DeviseAuthyController < DeviseController
|
|
|
61
67
|
if @authy_user.ok?
|
|
62
68
|
resource.authy_id = @authy_user.id
|
|
63
69
|
if resource.save
|
|
64
|
-
|
|
70
|
+
redirect_to [resource_name, :verify_authy_installation] and return
|
|
65
71
|
else
|
|
66
72
|
set_flash_message(:error, :not_enabled)
|
|
67
73
|
redirect_to after_authy_enabled_path_for(resource) and return
|
|
68
74
|
end
|
|
69
|
-
|
|
70
|
-
redirect_to [resource_name, :verify_authy_installation]
|
|
71
75
|
else
|
|
72
76
|
set_flash_message(:error, :not_enabled)
|
|
73
77
|
render :enable_authy
|
|
@@ -76,22 +80,39 @@ class Devise::DeviseAuthyController < DeviseController
|
|
|
76
80
|
|
|
77
81
|
# Disable 2FA
|
|
78
82
|
def POST_disable_authy
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
authy_id = resource.authy_id
|
|
84
|
+
resource.assign_attributes(:authy_enabled => false, :authy_id => nil)
|
|
85
|
+
resource.save(:validate => false)
|
|
86
|
+
|
|
87
|
+
other_resource = resource.class.find_by(:authy_id => authy_id)
|
|
88
|
+
if other_resource
|
|
89
|
+
# If another resource has the same authy_id, do not delete the user from
|
|
90
|
+
# the API.
|
|
84
91
|
forget_device
|
|
85
|
-
|
|
86
92
|
set_flash_message(:notice, :disabled)
|
|
87
93
|
else
|
|
88
|
-
|
|
94
|
+
response = Authy::API.delete_user(:id => authy_id)
|
|
95
|
+
if response.ok?
|
|
96
|
+
forget_device
|
|
97
|
+
set_flash_message(:notice, :disabled)
|
|
98
|
+
else
|
|
99
|
+
# If deleting the user from the API fails, set everything back to what
|
|
100
|
+
# it was before.
|
|
101
|
+
# I'm not sure this is a good idea, but it was existing behaviour.
|
|
102
|
+
# Could be changed in a major version bump.
|
|
103
|
+
resource.assign_attributes(:authy_enabled => true, :authy_id => authy_id)
|
|
104
|
+
resource.save(:validate => false)
|
|
105
|
+
set_flash_message(:error, :not_disabled)
|
|
106
|
+
end
|
|
89
107
|
end
|
|
90
|
-
|
|
91
108
|
redirect_to after_authy_disabled_path_for(resource)
|
|
92
109
|
end
|
|
93
110
|
|
|
94
111
|
def GET_verify_authy_installation
|
|
112
|
+
if resource_class.authy_enable_qr_code
|
|
113
|
+
response = Authy::API.request_qr_code(id: resource.authy_id)
|
|
114
|
+
@authy_qr_code = response.qr_code
|
|
115
|
+
end
|
|
95
116
|
render :verify_authy_installation
|
|
96
117
|
end
|
|
97
118
|
|
|
@@ -105,26 +126,34 @@ class Devise::DeviseAuthyController < DeviseController
|
|
|
105
126
|
self.resource.authy_enabled = token.ok?
|
|
106
127
|
|
|
107
128
|
if token.ok? && self.resource.save
|
|
129
|
+
remember_device(@resource.id) if params[:remember_device].to_i == 1
|
|
108
130
|
record_authy_authentication
|
|
109
131
|
set_flash_message(:notice, :enabled)
|
|
110
132
|
redirect_to after_authy_verified_path_for(resource)
|
|
111
133
|
else
|
|
134
|
+
if resource_class.authy_enable_qr_code
|
|
135
|
+
response = Authy::API.request_qr_code(id: resource.authy_id)
|
|
136
|
+
@authy_qr_code = response.qr_code
|
|
137
|
+
end
|
|
112
138
|
handle_invalid_token :verify_authy_installation, :not_enabled
|
|
113
139
|
end
|
|
114
140
|
end
|
|
115
141
|
|
|
116
142
|
def GET_authy_onetouch_status
|
|
117
|
-
|
|
143
|
+
response = Authy::OneTouch.approval_request_status(:uuid => params[:onetouch_uuid])
|
|
144
|
+
status = response.dig('approval_request', 'status')
|
|
118
145
|
case status
|
|
119
146
|
when 'pending'
|
|
120
147
|
head 202
|
|
121
148
|
when 'approved'
|
|
149
|
+
remember_device(@resource.id) if params[:remember_device].to_i == 1
|
|
150
|
+
remember_user
|
|
122
151
|
record_authy_authentication
|
|
123
152
|
render json: { redirect: after_sign_in_path_for(@resource) }
|
|
124
153
|
when 'denied'
|
|
125
154
|
head :unauthorized
|
|
126
155
|
else
|
|
127
|
-
head :
|
|
156
|
+
head :internal_server_error
|
|
128
157
|
end
|
|
129
158
|
end
|
|
130
159
|
|
|
@@ -172,6 +201,16 @@ class Devise::DeviseAuthyController < DeviseController
|
|
|
172
201
|
end
|
|
173
202
|
end
|
|
174
203
|
|
|
204
|
+
def check_resource_has_authy_id
|
|
205
|
+
redirect_to [resource_name, :enable_authy] if !resource.authy_id
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def check_resource_not_authy_enabled
|
|
209
|
+
if resource.authy_id && resource.authy_enabled
|
|
210
|
+
redirect_to after_authy_verified_path_for(resource)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
175
214
|
protected
|
|
176
215
|
|
|
177
216
|
def after_authy_enabled_path_for(resource)
|
|
@@ -202,4 +241,10 @@ class Devise::DeviseAuthyController < DeviseController
|
|
|
202
241
|
def after_account_is_locked
|
|
203
242
|
sign_out_and_redirect @resource
|
|
204
243
|
end
|
|
244
|
+
|
|
245
|
+
def remember_user
|
|
246
|
+
if session.delete("#{resource_name}_remember_me") == true && @resource.respond_to?(:remember_me=)
|
|
247
|
+
@resource.remember_me = true
|
|
248
|
+
end
|
|
249
|
+
end
|
|
205
250
|
end
|
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
class DeviseAuthy::PasswordsController < Devise::PasswordsController
|
|
2
|
+
##
|
|
3
|
+
# In the passwords controller a user can update their password using a
|
|
4
|
+
# recovery token. If `Devise.sign_in_after_reset_password` is `true` then the
|
|
5
|
+
# user is signed in immediately with the
|
|
6
|
+
# `Devise::Controllers::SignInOut#sign_in` method. However, if the user has
|
|
7
|
+
# 2FA enabled they should enter their second factor before they are signed in.
|
|
8
|
+
#
|
|
9
|
+
# This method overrides `Devise::Controllers::SignInOut#sign_in` but only
|
|
10
|
+
# within the `Devise::PasswordsController`. If the user needs to verify 2FA
|
|
11
|
+
# then `sign_in` returns `true`. This short circuits the method before it can
|
|
12
|
+
# call `warden.set_user` and log the user in.
|
|
13
|
+
#
|
|
14
|
+
# The user is redirected to `after_resetting_password_path_for(user)` at which
|
|
15
|
+
# point, since the user is not logged in, redirects again to sign in.
|
|
16
|
+
#
|
|
17
|
+
# This doesn't retain the expected behaviour of
|
|
18
|
+
# `Devise.sign_in_after_reset_password`, but is forgivable because this
|
|
19
|
+
# shouldn't be an avenue to bypass 2FA.
|
|
2
20
|
def sign_in(resource_or_scope, *args)
|
|
3
21
|
resource = args.last || resource_or_scope
|
|
4
22
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<%= verify_authy_form do %>
|
|
6
6
|
<legend><%= I18n.t('submit_token_title', {:scope => 'devise'}) %></legend>
|
|
7
7
|
<%= label_tag 'authy-token' %>
|
|
8
|
-
<%= text_field_tag :token, "", :autocomplete => :
|
|
8
|
+
<%= text_field_tag :token, "", :autocomplete => "one-time-code", :inputmode => "numeric", :pattern => "[0-9]*", :id => 'authy-token' %>
|
|
9
9
|
<label>
|
|
10
10
|
<%= check_box_tag :remember_device %>
|
|
11
11
|
<span><%= I18n.t('remember_device', {:scope => 'devise'}) %></span>
|
|
@@ -25,11 +25,12 @@
|
|
|
25
25
|
(function(){
|
|
26
26
|
var onetouchInterval = setInterval(function(){
|
|
27
27
|
var onetouchRequest = new XMLHttpRequest();
|
|
28
|
+
var rememberDevice = document.getElementById("remember_device").checked ? '1' : '0';
|
|
28
29
|
onetouchRequest.addEventListener("load", function(){
|
|
29
30
|
if(this.status != 202) clearInterval(onetouchInterval);
|
|
30
31
|
if(this.status == 200) window.location = JSON.parse(this.responseText).redirect;
|
|
31
32
|
});
|
|
32
|
-
onetouchRequest.open("GET", "<%= polymorphic_path [resource_name, :authy_onetouch_status] %>?onetouch_uuid=<%= @onetouch_uuid %>");
|
|
33
|
+
onetouchRequest.open("GET", "<%= polymorphic_path [resource_name, :authy_onetouch_status] %>?remember_device="+rememberDevice+"&onetouch_uuid=<%= @onetouch_uuid %>");
|
|
33
34
|
onetouchRequest.send();
|
|
34
35
|
}, 3000);
|
|
35
36
|
})();
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
%legend= I18n.t('submit_token_title', {:scope => 'devise'})
|
|
5
5
|
= hidden_field_tag :"#{resource_name}_id", @resource.id
|
|
6
6
|
= label_tag 'authy-token'
|
|
7
|
-
= text_field_tag :token, "", :autocomplete => :
|
|
7
|
+
= text_field_tag :token, "", :autocomplete => "one-time-code", :inputmode => "numeric", :pattern => "[0-9]*", :id => 'authy-token'
|
|
8
8
|
%label
|
|
9
9
|
= check_box_tag :remember_device
|
|
10
10
|
%span= I18n.t('remember_device', {:scope => 'devise'})
|
|
@@ -22,11 +22,12 @@
|
|
|
22
22
|
(function(){
|
|
23
23
|
var onetouchInterval = setInterval(function(){
|
|
24
24
|
var onetouchRequest = new XMLHttpRequest();
|
|
25
|
+
var rememberDevice = document.getElementById("remember_device").checked ? '1' : '0';
|
|
25
26
|
onetouchRequest.addEventListener("load", function(){
|
|
26
27
|
if(this.status != 202) clearInterval(onetouchInterval);
|
|
27
28
|
if(this.status == 200) window.location = JSON.parse(this.responseText).redirect;
|
|
28
29
|
});
|
|
29
|
-
onetouchRequest.open("GET", "#{polymorphic_path [resource_name, :authy_onetouch_status]}?onetouch_uuid=#{@onetouch_uuid}");
|
|
30
|
+
onetouchRequest.open("GET", "#{polymorphic_path [resource_name, :authy_onetouch_status]}?remember_device="+rememberDevice+"&onetouch_uuid=#{@onetouch_uuid}");
|
|
30
31
|
onetouchRequest.send();
|
|
31
32
|
}, 3000);
|
|
32
33
|
})();
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
<h2><%= I18n.t('authy_verify_installation_title', {:scope => 'devise'}) %></h2>
|
|
2
2
|
|
|
3
|
+
<% if @authy_qr_code %>
|
|
4
|
+
<%= image_tag @authy_qr_code, :size => '256x256', :alt => I18n.t('authy_qr_code_alt', {:scope => 'devise'}) %>
|
|
5
|
+
<p><%= I18n.t('authy_qr_code_instructions', {:scope => 'devise'}) %></p>
|
|
6
|
+
<% end %>
|
|
7
|
+
|
|
3
8
|
<%= verify_authy_installation_form do %>
|
|
4
9
|
<legend><%= I18n.t('submit_token_title', {:scope => 'devise'}) %></legend>
|
|
5
10
|
<%= label_tag :token %>
|
|
6
|
-
<%= text_field_tag :token, "", :autocomplete => :
|
|
11
|
+
<%= text_field_tag :token, "", :autocomplete => "one-time-code", :inputmode => "numeric", :pattern => "[0-9]*", :id => 'authy-token' %>
|
|
12
|
+
<label>
|
|
13
|
+
<%= check_box_tag :remember_device %>
|
|
14
|
+
<span><%= I18n.t('remember_device', {:scope => 'devise'}) %></span>
|
|
15
|
+
</label>
|
|
7
16
|
<%= authy_request_sms_link %>
|
|
8
17
|
<%= submit_tag I18n.t('enable_my_account', {:scope => 'devise'}), :class => 'btn' %>
|
|
9
|
-
<% end %>
|
|
10
|
-
|
|
18
|
+
<% end %>
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
%h2= I18n.t('authy_verify_installation_title', {:scope => 'devise'})
|
|
2
|
+
|
|
3
|
+
- if @authy_qr_code
|
|
4
|
+
= image_tag @authy_qr_code, :size => '256x256', :alt => I18n.t('authy_qr_code_alt', {:scope => 'devise'})
|
|
5
|
+
%p= I18n.t('authy_qr_code_instructions', {:scope => 'devise'})
|
|
6
|
+
|
|
2
7
|
= verify_authy_installation_form do
|
|
3
8
|
%legend= I18n.t('submit_token_title', {:scope => 'devise'})
|
|
4
9
|
= label_tag :token
|
|
5
|
-
= text_field_tag :token, "", :autocomplete => :
|
|
10
|
+
= text_field_tag :token, "", :autocomplete => "one-time-code", :inputmode => "numeric", :pattern => "[0-9]*", :id => 'authy-token'
|
|
11
|
+
%label
|
|
12
|
+
= check_box_tag :remember_device
|
|
13
|
+
%span= I18n.t('remember_device', {:scope => 'devise'})
|
|
6
14
|
= authy_request_sms_link
|
|
7
15
|
= submit_tag I18n.t('enable_my_account', {:scope => 'devise'}), :class => 'btn'
|
|
8
16
|
|
data/config.ru
ADDED
data/config/locales/en.yml
CHANGED
|
@@ -14,6 +14,9 @@ en:
|
|
|
14
14
|
authy_verify_installation_title: 'Verify your account'
|
|
15
15
|
enable_my_account: 'Enable my account'
|
|
16
16
|
|
|
17
|
+
authy_qr_code_alt: 'QR code for scanning with your authenticator app.'
|
|
18
|
+
authy_qr_code_instructions: 'Scan this QR code with your authenticator application and enter the code below.'
|
|
19
|
+
|
|
17
20
|
devise_authy:
|
|
18
21
|
user:
|
|
19
22
|
enabled: 'Two factor authentication was enabled'
|
data/devise-authy.gemspec
CHANGED
|
@@ -12,29 +12,39 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
|
|
13
13
|
spec.summary = %q{Authy plugin for Devise.}
|
|
14
14
|
spec.description = %q{Authy plugin to add two factor authentication to Devise.}
|
|
15
|
-
spec.homepage = "https://github.com/
|
|
15
|
+
spec.homepage = "https://github.com/twilio/authy-devise"
|
|
16
16
|
spec.license = "MIT"
|
|
17
17
|
|
|
18
18
|
spec.metadata = {
|
|
19
|
-
"bug_tracker_uri" => "https://github.com/
|
|
20
|
-
"change_log_uri" => "https://github.com/
|
|
21
|
-
"documentation_uri" => "https://github.com/
|
|
22
|
-
"homepage_uri" => "https://github.com/
|
|
23
|
-
"source_code_uri" => "https://github.com/
|
|
19
|
+
"bug_tracker_uri" => "https://github.com/twilio/authy-devise/issues",
|
|
20
|
+
"change_log_uri" => "https://github.com/twilio/authy-devise/blob/master/CHANGELOG.md",
|
|
21
|
+
"documentation_uri" => "https://github.com/twilio/authy-devise",
|
|
22
|
+
"homepage_uri" => "https://github.com/twilio/authy-devise",
|
|
23
|
+
"source_code_uri" => "https://github.com/twilio/authy-devise"
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
27
|
-
f.match(%r{^(test|spec|features
|
|
27
|
+
f.match(%r{^(test|spec|features)/})
|
|
28
28
|
end
|
|
29
29
|
spec.require_paths = ["lib"]
|
|
30
30
|
|
|
31
|
-
spec.add_dependency "devise", ">=
|
|
31
|
+
spec.add_dependency "devise", ">= 4.0.0"
|
|
32
32
|
spec.add_dependency "authy", ">= 2.7.5"
|
|
33
33
|
|
|
34
|
+
spec.add_development_dependency "appraisal", "~> 2.2"
|
|
34
35
|
spec.add_development_dependency "bundler", ">= 1.16"
|
|
35
|
-
spec.add_development_dependency "rake"
|
|
36
|
+
spec.add_development_dependency "rake"
|
|
37
|
+
spec.add_development_dependency "combustion", "~> 1.1"
|
|
36
38
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
39
|
+
spec.add_development_dependency "rspec-rails"
|
|
40
|
+
spec.add_development_dependency "rails-controller-testing", "~> 1.0"
|
|
37
41
|
spec.add_development_dependency "yard", "~> 0.9.11"
|
|
38
42
|
spec.add_development_dependency "rdoc", "~> 4.3.0"
|
|
39
|
-
spec.add_development_dependency "simplecov", "~> 0.
|
|
43
|
+
spec.add_development_dependency "simplecov", "~> 0.17.1"
|
|
44
|
+
spec.add_development_dependency "webmock", "~> 3.7.6"
|
|
45
|
+
spec.add_development_dependency "rails", ">= 5"
|
|
46
|
+
spec.add_development_dependency "sqlite3"
|
|
47
|
+
spec.add_development_dependency "generator_spec"
|
|
48
|
+
spec.add_development_dependency "database_cleaner", "~> 1.7"
|
|
49
|
+
spec.add_development_dependency "factory_bot_rails", "~> 5.1.1"
|
|
40
50
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "sdoc", "~> 0.4.0", group: :doc
|
|
6
|
+
gem "rails", "~> 5.2.0"
|
|
7
|
+
gem "sqlite3", "~> 1.3.13"
|
|
8
|
+
|
|
9
|
+
group :development, :test do
|
|
10
|
+
gem "factory_girl_rails", require: false
|
|
11
|
+
gem "rspec-rails", "~>4.0.0.beta3", require: false
|
|
12
|
+
gem "database_cleaner", require: false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "sdoc", "~> 0.4.0", group: :doc
|
|
6
|
+
gem "rails", "~> 6.0.0"
|
|
7
|
+
gem "sqlite3", "~> 1.4"
|
|
8
|
+
|
|
9
|
+
group :development, :test do
|
|
10
|
+
gem "factory_girl_rails", require: false
|
|
11
|
+
gem "rspec-rails", "~>4.0.0.beta3", require: false
|
|
12
|
+
gem "database_cleaner", require: false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
gemspec path: "../"
|
data/lib/devise-authy.rb
CHANGED
|
@@ -3,12 +3,11 @@ require 'active_support/core_ext/integer/time'
|
|
|
3
3
|
require 'devise'
|
|
4
4
|
require 'authy'
|
|
5
5
|
|
|
6
|
-
Authy.user_agent = "DeviseAuthy/#{DeviseAuthy::VERSION} - #{Authy.user_agent}"
|
|
7
|
-
|
|
8
6
|
module Devise
|
|
9
|
-
mattr_accessor :authy_remember_device, :authy_enable_onetouch
|
|
7
|
+
mattr_accessor :authy_remember_device, :authy_enable_onetouch, :authy_enable_qr_code
|
|
10
8
|
@@authy_remember_device = 1.month
|
|
11
9
|
@@authy_enable_onetouch = false
|
|
10
|
+
@@authy_enable_qr_code = false
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
module DeviseAuthy
|
|
@@ -30,5 +29,7 @@ require 'devise-authy/models/authy_authenticatable'
|
|
|
30
29
|
require 'devise-authy/models/authy_lockable'
|
|
31
30
|
require 'devise-authy/version'
|
|
32
31
|
|
|
32
|
+
Authy.user_agent = "DeviseAuthy/#{DeviseAuthy::VERSION} - #{Authy.user_agent}"
|
|
33
|
+
|
|
33
34
|
Devise.add_module :authy_authenticatable, :model => 'devise-authy/models/authy_authenticatable', :controller => :devise_authy, :route => :authy
|
|
34
35
|
Devise.add_module :authy_lockable, :model => 'devise-authy/models/authy_lockable'
|
|
@@ -9,11 +9,11 @@ module DeviseAuthy
|
|
|
9
9
|
|
|
10
10
|
private
|
|
11
11
|
|
|
12
|
-
def remember_device
|
|
13
|
-
id = @resource.id
|
|
12
|
+
def remember_device(id)
|
|
14
13
|
cookies.signed[:remember_device] = {
|
|
15
14
|
:value => {expires: Time.now.to_i, id: id}.to_json,
|
|
16
15
|
:secure => !(Rails.env.test? || Rails.env.development?),
|
|
16
|
+
:httponly => !(Rails.env.test? || Rails.env.development?),
|
|
17
17
|
:expires => resource_class.authy_remember_device.from_now
|
|
18
18
|
}
|
|
19
19
|
end
|
|
@@ -40,7 +40,7 @@ module DeviseAuthy
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def is_signing_in?
|
|
43
|
-
if devise_controller? &&
|
|
43
|
+
if devise_controller? &&
|
|
44
44
|
is_devise_sessions_controller? &&
|
|
45
45
|
self.action_name == "create"
|
|
46
46
|
return true
|
|
@@ -76,8 +76,8 @@ module DeviseAuthy
|
|
|
76
76
|
send(:"#{scope}_verify_authy_path")
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
def send_one_touch_request
|
|
80
|
-
Authy::OneTouch.send_approval_request(id:
|
|
79
|
+
def send_one_touch_request(authy_id)
|
|
80
|
+
Authy::OneTouch.send_approval_request(id: authy_id, message: I18n.t('request_to_login', { :scope => 'devise' }))
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def record_authy_authentication
|
|
@@ -17,7 +17,7 @@ module Devise
|
|
|
17
17
|
where(authy_id: authy_id).first
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
Devise::Models.config(self, :authy_remember_device, :authy_enable_onetouch)
|
|
20
|
+
Devise::Models.config(self, :authy_remember_device, :authy_enable_onetouch, :authy_enable_qr_code)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
data/lib/devise-authy/version.rb
CHANGED
|
@@ -11,12 +11,12 @@ module ActiveRecord
|
|
|
11
11
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
|
-
def
|
|
15
|
-
Rails
|
|
14
|
+
def versioned_migrations?
|
|
15
|
+
Rails::VERSION::MAJOR >= 5
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def migration_version
|
|
19
|
-
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if
|
|
19
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" if versioned_migrations?
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module DeviseAuthy
|
|
2
4
|
module Generators
|
|
3
5
|
class DeviseAuthyGenerator < Rails::Generators::NamedBase
|
|
@@ -7,7 +9,7 @@ module DeviseAuthy
|
|
|
7
9
|
desc "Add :authy_authenticatable directive in the given model, plus accessors. Also generate migration for ActiveRecord"
|
|
8
10
|
|
|
9
11
|
def inject_devise_authy_content
|
|
10
|
-
path = File.join("app","models","#{file_path}.rb")
|
|
12
|
+
path = File.join(destination_root, "app","models","#{file_path}.rb")
|
|
11
13
|
if File.exists?(path) &&
|
|
12
14
|
!File.read(path).include?("authy_authenticatable")
|
|
13
15
|
inject_into_file(path,
|
|
@@ -19,7 +21,7 @@ module DeviseAuthy
|
|
|
19
21
|
!File.read(path).include?(":authy_id")
|
|
20
22
|
inject_into_file(path,
|
|
21
23
|
":authy_id, :last_sign_in_with_authy, ",
|
|
22
|
-
:after => "attr_accessible ")
|
|
24
|
+
:after => "attr_accessible ")
|
|
23
25
|
end
|
|
24
26
|
end
|
|
25
27
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
require "rails/generators"
|
|
2
|
+
|
|
1
3
|
module DeviseAuthy
|
|
2
4
|
module Generators
|
|
3
5
|
# Install Generator
|
|
4
|
-
class InstallGenerator < Rails::Generators::Base
|
|
6
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
5
7
|
source_root File.expand_path("../../templates", __FILE__)
|
|
6
8
|
|
|
7
9
|
class_option :haml, :type => :boolean, :required => false, :default => false, :desc => "Generate views in Haml"
|
|
@@ -15,8 +17,10 @@ module DeviseAuthy
|
|
|
15
17
|
" # How long should the user's device be remembered for.\n" +
|
|
16
18
|
" # config.authy_remember_device = 1.month\n\n" +
|
|
17
19
|
" # Should Authy OneTouch be enabled?\n" +
|
|
18
|
-
" # config.authy_enable_onetouch = false\n\n"
|
|
19
|
-
|
|
20
|
+
" # config.authy_enable_onetouch = false\n\n" +
|
|
21
|
+
" # Should generating QR codes for other authenticator apps be enabled?\n" +
|
|
22
|
+
" # Note: you need to enable this in your Twilio console.\n" +
|
|
23
|
+
" # config.authy_enable_qr_code = false\n\n", :after => "Devise.setup do |config|\n"
|
|
20
24
|
end
|
|
21
25
|
|
|
22
26
|
def add_initializer
|
|
@@ -61,14 +65,14 @@ module DeviseAuthy
|
|
|
61
65
|
@
|
|
62
66
|
},
|
|
63
67
|
:erb => {
|
|
64
|
-
:before => %r{\s
|
|
68
|
+
:before => %r{\s*<\/\s*head\s*>\s*},
|
|
65
69
|
:content => %@
|
|
66
70
|
<%=javascript_include_tag "https://www.authy.com/form.authy.min.js" %>
|
|
67
71
|
<%=stylesheet_link_tag "https://www.authy.com/form.authy.min.css" %>
|
|
68
72
|
@
|
|
69
73
|
}
|
|
70
74
|
}.each do |extension, opts|
|
|
71
|
-
file_path = "app
|
|
75
|
+
file_path = File.join(destination_root, "app", "views", "layouts", "application.html.#{extension}")
|
|
72
76
|
if File.exists?(file_path) && !File.read(file_path).include?("form.authy.min.js")
|
|
73
77
|
inject_into_file(file_path, opts.delete(:content), opts)
|
|
74
78
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: devise-authy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Authy Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-10-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: devise
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 4.0.0
|
|
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:
|
|
26
|
+
version: 4.0.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: authy
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: 2.7.5
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: appraisal
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '2.2'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '2.2'
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: bundler
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -54,18 +68,32 @@ dependencies:
|
|
|
54
68
|
version: '1.16'
|
|
55
69
|
- !ruby/object:Gem::Dependency
|
|
56
70
|
name: rake
|
|
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: combustion
|
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
|
58
86
|
requirements:
|
|
59
87
|
- - "~>"
|
|
60
88
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
89
|
+
version: '1.1'
|
|
62
90
|
type: :development
|
|
63
91
|
prerelease: false
|
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
93
|
requirements:
|
|
66
94
|
- - "~>"
|
|
67
95
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
96
|
+
version: '1.1'
|
|
69
97
|
- !ruby/object:Gem::Dependency
|
|
70
98
|
name: rspec
|
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,6 +108,34 @@ dependencies:
|
|
|
80
108
|
- - "~>"
|
|
81
109
|
- !ruby/object:Gem::Version
|
|
82
110
|
version: '3.0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rspec-rails
|
|
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-controller-testing
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '1.0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '1.0'
|
|
83
139
|
- !ruby/object:Gem::Dependency
|
|
84
140
|
name: yard
|
|
85
141
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,14 +170,98 @@ dependencies:
|
|
|
114
170
|
requirements:
|
|
115
171
|
- - "~>"
|
|
116
172
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 0.
|
|
173
|
+
version: 0.17.1
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - "~>"
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: 0.17.1
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: webmock
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - "~>"
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: 3.7.6
|
|
188
|
+
type: :development
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - "~>"
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: 3.7.6
|
|
195
|
+
- !ruby/object:Gem::Dependency
|
|
196
|
+
name: rails
|
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
|
198
|
+
requirements:
|
|
199
|
+
- - ">="
|
|
200
|
+
- !ruby/object:Gem::Version
|
|
201
|
+
version: '5'
|
|
202
|
+
type: :development
|
|
203
|
+
prerelease: false
|
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
205
|
+
requirements:
|
|
206
|
+
- - ">="
|
|
207
|
+
- !ruby/object:Gem::Version
|
|
208
|
+
version: '5'
|
|
209
|
+
- !ruby/object:Gem::Dependency
|
|
210
|
+
name: sqlite3
|
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
|
212
|
+
requirements:
|
|
213
|
+
- - ">="
|
|
214
|
+
- !ruby/object:Gem::Version
|
|
215
|
+
version: '0'
|
|
216
|
+
type: :development
|
|
217
|
+
prerelease: false
|
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
219
|
+
requirements:
|
|
220
|
+
- - ">="
|
|
221
|
+
- !ruby/object:Gem::Version
|
|
222
|
+
version: '0'
|
|
223
|
+
- !ruby/object:Gem::Dependency
|
|
224
|
+
name: generator_spec
|
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
|
226
|
+
requirements:
|
|
227
|
+
- - ">="
|
|
228
|
+
- !ruby/object:Gem::Version
|
|
229
|
+
version: '0'
|
|
230
|
+
type: :development
|
|
231
|
+
prerelease: false
|
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
233
|
+
requirements:
|
|
234
|
+
- - ">="
|
|
235
|
+
- !ruby/object:Gem::Version
|
|
236
|
+
version: '0'
|
|
237
|
+
- !ruby/object:Gem::Dependency
|
|
238
|
+
name: database_cleaner
|
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
|
240
|
+
requirements:
|
|
241
|
+
- - "~>"
|
|
242
|
+
- !ruby/object:Gem::Version
|
|
243
|
+
version: '1.7'
|
|
244
|
+
type: :development
|
|
245
|
+
prerelease: false
|
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
247
|
+
requirements:
|
|
248
|
+
- - "~>"
|
|
249
|
+
- !ruby/object:Gem::Version
|
|
250
|
+
version: '1.7'
|
|
251
|
+
- !ruby/object:Gem::Dependency
|
|
252
|
+
name: factory_bot_rails
|
|
253
|
+
requirement: !ruby/object:Gem::Requirement
|
|
254
|
+
requirements:
|
|
255
|
+
- - "~>"
|
|
256
|
+
- !ruby/object:Gem::Version
|
|
257
|
+
version: 5.1.1
|
|
118
258
|
type: :development
|
|
119
259
|
prerelease: false
|
|
120
260
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
261
|
requirements:
|
|
122
262
|
- - "~>"
|
|
123
263
|
- !ruby/object:Gem::Version
|
|
124
|
-
version:
|
|
264
|
+
version: 5.1.1
|
|
125
265
|
description: Authy plugin to add two factor authentication to Devise.
|
|
126
266
|
email:
|
|
127
267
|
- support@authy.com
|
|
@@ -133,6 +273,7 @@ files:
|
|
|
133
273
|
- ".gitignore"
|
|
134
274
|
- ".rspec"
|
|
135
275
|
- ".travis.yml"
|
|
276
|
+
- Appraisals
|
|
136
277
|
- CHANGELOG.md
|
|
137
278
|
- Gemfile
|
|
138
279
|
- LICENSE.txt
|
|
@@ -149,8 +290,12 @@ files:
|
|
|
149
290
|
- app/views/devise/verify_authy.html.haml
|
|
150
291
|
- app/views/devise/verify_authy_installation.html.erb
|
|
151
292
|
- app/views/devise/verify_authy_installation.html.haml
|
|
293
|
+
- config.ru
|
|
152
294
|
- config/locales/en.yml
|
|
153
295
|
- devise-authy.gemspec
|
|
296
|
+
- gemfiles/.bundle/config
|
|
297
|
+
- gemfiles/rails_5_2.gemfile
|
|
298
|
+
- gemfiles/rails_6.gemfile
|
|
154
299
|
- lib/devise-authy.rb
|
|
155
300
|
- lib/devise-authy/controllers/helpers.rb
|
|
156
301
|
- lib/devise-authy/controllers/view_helpers.rb
|
|
@@ -165,15 +310,15 @@ files:
|
|
|
165
310
|
- lib/generators/active_record/templates/migration.rb
|
|
166
311
|
- lib/generators/devise_authy/devise_authy_generator.rb
|
|
167
312
|
- lib/generators/devise_authy/install_generator.rb
|
|
168
|
-
homepage: https://github.com/
|
|
313
|
+
homepage: https://github.com/twilio/authy-devise
|
|
169
314
|
licenses:
|
|
170
315
|
- MIT
|
|
171
316
|
metadata:
|
|
172
|
-
bug_tracker_uri: https://github.com/
|
|
173
|
-
change_log_uri: https://github.com/
|
|
174
|
-
documentation_uri: https://github.com/
|
|
175
|
-
homepage_uri: https://github.com/
|
|
176
|
-
source_code_uri: https://github.com/
|
|
317
|
+
bug_tracker_uri: https://github.com/twilio/authy-devise/issues
|
|
318
|
+
change_log_uri: https://github.com/twilio/authy-devise/blob/master/CHANGELOG.md
|
|
319
|
+
documentation_uri: https://github.com/twilio/authy-devise
|
|
320
|
+
homepage_uri: https://github.com/twilio/authy-devise
|
|
321
|
+
source_code_uri: https://github.com/twilio/authy-devise
|
|
177
322
|
post_install_message:
|
|
178
323
|
rdoc_options: []
|
|
179
324
|
require_paths:
|
|
@@ -189,7 +334,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
189
334
|
- !ruby/object:Gem::Version
|
|
190
335
|
version: '0'
|
|
191
336
|
requirements: []
|
|
192
|
-
rubygems_version: 3.0.
|
|
337
|
+
rubygems_version: 3.0.3
|
|
193
338
|
signing_key:
|
|
194
339
|
specification_version: 4
|
|
195
340
|
summary: Authy plugin for Devise.
|