devise-passkeys 0.1.0 → 0.3.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: 2447f73b6085c64f92155f7fbef7e0fec400c1d0850e267bd75d0c5f5d1c5131
4
- data.tar.gz: 4574971ab7925b50c8513273c9dd077e09732a22952533c7a92ceabee7071115
3
+ metadata.gz: 66ad22c45235ff6c913652a436ce925edca3a8088d657b4ab98d8a2ed57dd863
4
+ data.tar.gz: 718f3ac80d832c87246a7e4abbf868d41fe1b94a402ebb4869fe873aab374bc8
5
5
  SHA512:
6
- metadata.gz: a0be4cd6b62abe8589b238b09684abaed8a1434cc3377880111dbb521edea92a085fd4d108490bc0bafb0270d642bc1b1426d4141420fce7198aa14e3d7da47c
7
- data.tar.gz: 93752f8ef25cb01502abc1420d6fda0861a43719ab38dfd843b5699ec6f51126668e91da6bc5fce681f94c153c3a64d192b19829657bbedd4945a4f9e68b62ca
6
+ metadata.gz: 7d732ec8a15cfc1cb41d8a72d1e9c049d271648a0dae14596e627a23e6a52368a47b9df79073e43b35d0d1d28362a75d09e0a1c2b2da38f420cf68a7168dcccf
7
+ data.tar.gz: 400fdc543f5edf4bd5ed30ee1d0bd3a8f8e841435ee3c95c108a422162f534289a05f3ea128be2444f61e30a4735f1aa99e09eeee5cba68cc268ab5ccc79f25a
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown
data/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
- ## [Unreleased]
1
+ ## [0.3.0] - 2023-08-18
2
2
 
3
- ## [0.1.0] - 2022-10-13
3
+ ### Bugfixes
4
+
5
+ - Remove default `Devise.add_module`, remove incorrect `no_input: true` declaration in documentation
6
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/48
7
+
8
+ ## [0.2.0] - 2023-07-07
9
+
10
+ ### Bugfixes
11
+ - Fixed bug with `Devise::Strategies::PasskeyReauthentication` clearing the CSRF token after reauthentication
12
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/45
13
+ - Fixed bug where `RegistrationsControllerConcern` was using `:user` as the Strong Parameters key, rather than `resource_key`
14
+ - https://github.com/ruby-passkeys/devise-passkeys/commit/5ef8c83ffe57b3719ab574a01c710ee3ba7dcfb1
15
+ - Rename `create_resource_and_passkey` => `create_passkey_for_resource`
16
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/37
17
+ - `ReauthenticationControllerConcern` and `SessionsControllerConcern` raise `NoMethodError` if the `relying_party` has not been overridden
18
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/32
19
+
20
+ ### Refactoring
21
+
22
+ - Refactor PasskeysControllerConcern to have clearer credential verify with `verify_credential_integrity`
23
+ -https://github.com/ruby-passkeys/devise-passkeys/pull/29/commits/f1400cb4b217c20b9e74fda3f55f74284e373d25
24
+ - Refactor Controller concerns to not use `Warden::WebAuthn::StrategyHelpers`
25
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/29
26
+ - Rename `Devise::Passkeys::Controllers::Concerns::PasskeyReauthentication` => `Devise::Passkeys::Controllers::Concerns::Reauthentication`
27
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/7/
28
+ - Add `passkey:` keyword param to `after_passkey_authentication` callback
29
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/26
30
+ - Removed unused `:maximum_passkeys_per_user` attribute
31
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/41
32
+
33
+ ### Etc.
34
+ - Bump to warden-webauthn 0.2.1
35
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/29/commits/d825ffded91aa98801bdd5530442761aa60538f9
36
+ - Use `Warden::WebAuthn::RackHelper.set_relying_party_in_request_env` to streamline setup
37
+ https://github.com/ruby-passkeys/devise-passkeys/pull/29/commits/7b7d50129ebe83b0a224d0ace0e4cff8ea407f4a
38
+ - Bump `Devise` requirement to `>= 4.7.1`
39
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/11
40
+ - Documentation
41
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/12
42
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/44
43
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/43
44
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/39
45
+ - https://github.com/ruby-passkeys/devise-passkeys/pull/38
46
+
47
+
48
+ ## [0.1.0] - 2023-05-07
4
49
 
5
50
  - Initial release
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,47 @@
1
+ # Contributing
2
+
3
+ ## Installation
4
+
5
+ After checking out the repo, run the following to install both Bundler and Appraisal dependencies:
6
+
7
+ ```sh
8
+ bin/setup
9
+ ```
10
+
11
+ # Run tests
12
+
13
+ To run the test suite for all Appraisal variants, run:
14
+
15
+ ```sh
16
+ bundle exec appraisal rake test
17
+ ```
18
+
19
+ or
20
+
21
+ ```sh
22
+ bin/test
23
+ ```
24
+
25
+ ## Writing Documentation
26
+
27
+ Documentation is written using [YARD](http://yardoc.org/).
28
+
29
+ You can start a YARD server to view the generated documentation (with automatic reloading) by running:
30
+
31
+ ```sh
32
+ bin/yard
33
+ ```
34
+
35
+ The documentation site will now be available at [http://localhost:8808](http://localhost:8808)
36
+
37
+ ## Interactive Console
38
+
39
+ You can also run the following for an interactive prompt that will allow you to experiment:
40
+
41
+ ```sh
42
+ bin/console
43
+ ```
44
+
45
+ # Gem installation & cutting
46
+
47
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
data/Gemfile CHANGED
@@ -10,6 +10,8 @@ group :development, :test do
10
10
  gem "debug"
11
11
  gem "rake", "~> 13.0"
12
12
  gem "rubocop", "~> 1.21"
13
+ gem 'yard'
14
+ gem 'webrick'
13
15
  end
14
16
 
15
17
  group :test do
data/Gemfile.lock CHANGED
@@ -1,19 +1,32 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devise-passkeys (0.1.0)
5
- devise
6
- warden-webauthn (>= 0.2.0)
4
+ devise-passkeys (0.3.0)
5
+ devise (>= 4.7.1)
6
+ warden-webauthn (>= 0.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activemodel (7.0.4.2)
12
- activesupport (= 7.0.4.2)
13
- activerecord (7.0.4.2)
14
- activemodel (= 7.0.4.2)
15
- activesupport (= 7.0.4.2)
16
- activesupport (7.0.4.2)
11
+ actionpack (7.0.6)
12
+ actionview (= 7.0.6)
13
+ activesupport (= 7.0.6)
14
+ rack (~> 2.0, >= 2.2.4)
15
+ rack-test (>= 0.6.3)
16
+ rails-dom-testing (~> 2.0)
17
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
18
+ actionview (7.0.6)
19
+ activesupport (= 7.0.6)
20
+ builder (~> 3.1)
21
+ erubi (~> 1.4)
22
+ rails-dom-testing (~> 2.0)
23
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
24
+ activemodel (7.0.6)
25
+ activesupport (= 7.0.6)
26
+ activerecord (7.0.6)
27
+ activemodel (= 7.0.6)
28
+ activesupport (= 7.0.6)
29
+ activesupport (7.0.6)
17
30
  concurrent-ruby (~> 1.0, >= 1.0.2)
18
31
  i18n (>= 1.6, < 2)
19
32
  minitest (>= 5.1)
@@ -25,16 +38,16 @@ GEM
25
38
  thor (>= 0.14.0)
26
39
  ast (2.4.2)
27
40
  awrence (1.2.1)
28
- bcrypt (3.1.18)
29
- bcrypt-ruby (3.1.5)
30
- bcrypt (>= 3.1.3)
41
+ bcrypt (3.1.19)
31
42
  bindata (2.4.15)
32
43
  bson (4.15.0)
44
+ builder (3.2.4)
33
45
  cbor (0.5.9.6)
34
- concurrent-ruby (1.2.0)
46
+ concurrent-ruby (1.2.2)
35
47
  cose (1.3.0)
36
48
  cbor (~> 0.5.9)
37
49
  openssl-signature_algorithm (~> 1.0)
50
+ crass (1.0.6)
38
51
  database_cleaner-active_record (2.1.0)
39
52
  activerecord (>= 5.a)
40
53
  database_cleaner-core (~> 2.0.0)
@@ -42,61 +55,95 @@ GEM
42
55
  database_cleaner-mongoid (2.0.1)
43
56
  database_cleaner-core (~> 2.0.0)
44
57
  mongoid
45
- debug (1.7.1)
58
+ debug (1.8.0)
46
59
  irb (>= 1.5.0)
47
60
  reline (>= 0.3.1)
48
- devise (1.5.4)
49
- bcrypt-ruby (~> 3.0)
50
- orm_adapter (~> 0.0.3)
51
- warden (~> 1.1)
61
+ devise (4.9.2)
62
+ bcrypt (~> 3.0)
63
+ orm_adapter (~> 0.1)
64
+ railties (>= 4.1.0)
65
+ responders
66
+ warden (~> 1.2.3)
52
67
  docile (1.4.0)
53
- i18n (1.12.0)
68
+ erubi (1.12.0)
69
+ i18n (1.14.1)
54
70
  concurrent-ruby (~> 1.0)
55
71
  io-console (0.6.0)
56
- irb (1.6.2)
72
+ irb (1.7.1)
57
73
  reline (>= 0.3.0)
58
74
  json (2.6.3)
59
- jwt (2.7.0)
75
+ jwt (2.7.1)
76
+ language_server-protocol (3.17.0.3)
77
+ loofah (2.21.3)
78
+ crass (~> 1.0.2)
79
+ nokogiri (>= 1.12.0)
60
80
  m (1.6.1)
61
81
  method_source (>= 0.6.7)
62
82
  rake (>= 0.9.2.2)
63
83
  method_source (1.0.0)
64
- minitest (5.17.0)
84
+ minitest (5.18.1)
65
85
  minitest-ci (3.4.0)
66
86
  minitest (>= 5.0.6)
67
- mongo (2.18.2)
87
+ mongo (2.19.0)
68
88
  bson (>= 4.14.1, < 5.0.0)
69
- mongoid (8.0.3)
89
+ mongoid (8.1.0)
70
90
  activemodel (>= 5.1, < 7.1, != 7.0.0)
91
+ concurrent-ruby (>= 1.0.5, < 2.0)
71
92
  mongo (>= 2.18.0, < 3.0.0)
72
93
  ruby2_keywords (~> 0.0.5)
94
+ nokogiri (1.15.3-arm64-darwin)
95
+ racc (~> 1.4)
96
+ nokogiri (1.15.3-x86_64-linux)
97
+ racc (~> 1.4)
73
98
  openssl (3.1.0)
74
99
  openssl-signature_algorithm (1.3.0)
75
100
  openssl (> 2.0)
76
- orm_adapter (0.0.7)
77
- parallel (1.22.1)
78
- parser (3.2.1.0)
101
+ orm_adapter (0.5.0)
102
+ parallel (1.23.0)
103
+ parser (3.2.2.3)
79
104
  ast (~> 2.4.1)
80
- rack (3.0.4.1)
105
+ racc
106
+ racc (1.7.1)
107
+ rack (2.2.8)
108
+ rack-test (2.1.0)
109
+ rack (>= 1.3)
110
+ rails-dom-testing (2.1.1)
111
+ activesupport (>= 5.0.0)
112
+ minitest
113
+ nokogiri (>= 1.6)
114
+ rails-html-sanitizer (1.6.0)
115
+ loofah (~> 2.21)
116
+ nokogiri (~> 1.14)
117
+ railties (7.0.6)
118
+ actionpack (= 7.0.6)
119
+ activesupport (= 7.0.6)
120
+ method_source
121
+ rake (>= 12.2)
122
+ thor (~> 1.0)
123
+ zeitwerk (~> 2.5)
81
124
  rainbow (3.1.1)
82
125
  rake (13.0.6)
83
- regexp_parser (2.7.0)
84
- reline (0.3.2)
126
+ regexp_parser (2.8.1)
127
+ reline (0.3.5)
85
128
  io-console (~> 0.5)
129
+ responders (3.1.0)
130
+ actionpack (>= 5.2)
131
+ railties (>= 5.2)
86
132
  rexml (3.2.5)
87
- rubocop (1.45.1)
133
+ rubocop (1.54.1)
88
134
  json (~> 2.3)
135
+ language_server-protocol (>= 3.17.0)
89
136
  parallel (~> 1.10)
90
- parser (>= 3.2.0.0)
137
+ parser (>= 3.2.2.3)
91
138
  rainbow (>= 2.2.2, < 4.0)
92
139
  regexp_parser (>= 1.8, < 3.0)
93
140
  rexml (>= 3.2.5, < 4.0)
94
- rubocop-ast (>= 1.24.1, < 2.0)
141
+ rubocop-ast (>= 1.28.0, < 2.0)
95
142
  ruby-progressbar (~> 1.7)
96
143
  unicode-display_width (>= 2.4.0, < 3.0)
97
- rubocop-ast (1.26.0)
144
+ rubocop-ast (1.29.0)
98
145
  parser (>= 3.2.1.0)
99
- ruby-progressbar (1.11.0)
146
+ ruby-progressbar (1.13.0)
100
147
  ruby2_keywords (0.0.5)
101
148
  safety_net_attestation (0.4.0)
102
149
  jwt (~> 2.0)
@@ -106,7 +153,7 @@ GEM
106
153
  simplecov_json_formatter (~> 0.1)
107
154
  simplecov-html (0.12.3)
108
155
  simplecov_json_formatter (0.1.4)
109
- thor (1.2.1)
156
+ thor (1.2.2)
110
157
  tpm-key_attestation (0.12.0)
111
158
  bindata (~> 2.4)
112
159
  openssl (> 2.0)
@@ -116,7 +163,7 @@ GEM
116
163
  unicode-display_width (2.4.2)
117
164
  warden (1.2.9)
118
165
  rack (>= 2.0.9)
119
- warden-webauthn (0.2.0)
166
+ warden-webauthn (0.3.0)
120
167
  warden
121
168
  webauthn (>= 3)
122
169
  webauthn (3.0.0)
@@ -128,6 +175,9 @@ GEM
128
175
  openssl (>= 2.2)
129
176
  safety_net_attestation (~> 0.4.0)
130
177
  tpm-key_attestation (~> 0.12.0)
178
+ webrick (1.8.1)
179
+ yard (0.9.34)
180
+ zeitwerk (2.6.8)
131
181
 
132
182
  PLATFORMS
133
183
  arm64-darwin-21
@@ -146,6 +196,8 @@ DEPENDENCIES
146
196
  rake (~> 13.0)
147
197
  rubocop (~> 1.21)
148
198
  simplecov
199
+ webrick
200
+ yard
149
201
 
150
202
  BUNDLED WITH
151
- 2.3.7
203
+ 2.4.12
data/README.md CHANGED
@@ -19,7 +19,7 @@ $ bundle
19
19
 
20
20
  # Usage
21
21
 
22
- 1. Add `:passkey_authenticatable` in your Devise-enabled model
22
+ ## Add `:passkey_authenticatable`
23
23
 
24
24
  ```ruby
25
25
  class User < ApplicationRecord
@@ -35,7 +35,7 @@ class User < ApplicationRecord
35
35
  self.find_by(id: passkey.user.id)
36
36
  end
37
37
 
38
- def after_passkey_authentication
38
+ def after_passkey_authentication(passkey:)
39
39
  end
40
40
  end
41
41
  ```
@@ -47,7 +47,7 @@ The Devise-enabled model must have a `webauthn_id` field in the model; which is:
47
47
 
48
48
  This will allow you to explictly establish the relationship between a user & its passkeys (to help both your app & the user's authenticator with credential management)
49
49
 
50
- 2. Generate the model that will store passkeys. The model name is not important, but the Devise-enabled model should have:
50
+ ## Generate the Model That Will Store Passkeys. Should Have:
51
51
  - A `has_many :passkeys` association
52
52
  - A `passkey_class` class method that returns the passkey class
53
53
  - A `find_for_passkey(passkey)` class method that finds the user for a given passkey
@@ -66,7 +66,7 @@ The following fields are required:
66
66
 
67
67
  It's recommended to add unique indexes on `external_id` and `public_key`
68
68
 
69
- 3. Generate custom devise controllers & views for your Devise-enabled model
69
+ ## Generate Custom Devise Controllers & Views
70
70
 
71
71
  [Since Devise does not have built-in passkeys support yet](https://github.com/heartcombo/devise/issues/5527), you'll need to customize both the controllers & the views
72
72
 
@@ -77,7 +77,7 @@ rails generate devise:views users
77
77
 
78
78
  If you're trying to keep your codebase small, these instructions only concern the `Users::SessionsController` & `Users::RegistrationsController`, so you can delete any other generated custom controllers if needed. You will likely need to modify the `views/users/shared/*` partials though, because they assume passwords are being used.
79
79
 
80
- 4. Include the passkeys concerns into your controllers
80
+ ## Include the Passkeys Concerns in Your Controllers
81
81
 
82
82
  Rather than having base classes, `Devise::Passkeys` has a series of concerns that can be mixed into your controllers. This allows you to change behavior, and does not keep you stuck down a path that could be incompatible with your existing authentication setup.
83
83
 
@@ -96,10 +96,6 @@ class Users::SessionsController < Devise::SessionsController
96
96
  def relying_party
97
97
  WebAuthn::RelyingParty.new(...)
98
98
  end
99
-
100
- def set_relying_party_in_request_env
101
- request.env[relying_party_key] = relying_party
102
- end
103
99
  end
104
100
 
105
101
  # frozen_string_literal: true
@@ -111,10 +107,6 @@ class Users::ReauthenticationController < DeviseController
111
107
  def relying_party
112
108
  WebAuthn::RelyingParty.new(...)
113
109
  end
114
-
115
- def set_relying_party_in_request_env
116
- request.env[relying_party_key] = relying_party
117
- end
118
110
  end
119
111
 
120
112
  # frozen_string_literal: true
@@ -126,15 +118,11 @@ class Users::PasskeysController < DeviseController
126
118
  def relying_party
127
119
  WebAuthn::RelyingParty.new(...)
128
120
  end
129
-
130
- def set_relying_party_in_request_env
131
- request.env[relying_party_key] = relying_party
132
- end
133
121
  end
134
122
 
135
123
  ```
136
124
 
137
- 6. Add necessary routes
125
+ ## Add Routes
138
126
 
139
127
  Given the customization routes usually require, you'll need to hook up the routes yourself. Here's an example:
140
128
 
@@ -165,6 +153,21 @@ devise_scope :user do
165
153
  end
166
154
  ```
167
155
 
156
+ ## Reimplement the `:passkey_authenticatable` Module
157
+
158
+ **Important**: You will need to reimplement the `:passkey_authenticatable` Devise module. This will override the module definition with your implementation specific definitions; pointing to the specific route, controller, etc.
159
+
160
+ Here's an example from [devise-passkeys-template](https://github.com/ruby-passkeys/devise-passkeys-template/blob/main/app/models/user.rb#L18):
161
+
162
+ ```ruby
163
+ Devise.add_module :passkey_authenticatable,
164
+ model: 'devise/passkeys/model',
165
+ route: {session: [nil, :new, :create, :destroy] },
166
+ controller: 'controller/sessions',
167
+ strategy: true
168
+ ```
169
+
170
+ # FAQs
168
171
 
169
172
  ## What about the Webauthn javascript? Mailers? Error handling?
170
173
 
@@ -176,13 +179,11 @@ Here's a template repo! https://github.com/ruby-passkeys/devise-passkeys-templat
176
179
 
177
180
  ## Development
178
181
 
179
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
180
-
181
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
182
+ Please see [CONTRIBUTING.md](https://github.com/ruby-passkeys/devise-passkeys/blob/main/CONTRIBUTING.md) for guidance on how to help out!
182
183
 
183
184
  ## Contributing
184
185
 
185
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/devise-passkeys. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/devise-passkeys/blob/main/CODE_OF_CONDUCT.md).
186
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby-passkeys/devise-passkeys. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/ruby-passkeys/devise-passkeys/blob/main/CODE_OF_CONDUCT.md).
186
187
 
187
188
  ## License
188
189
 
@@ -190,7 +191,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
190
191
 
191
192
  ## Code of Conduct
192
193
 
193
- Everyone interacting in the Devise::Passkeys project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/devise-passkeys/blob/main/CODE_OF_CONDUCT.md).
194
+ Everyone interacting in the Devise::Passkeys project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ruby-passkeys/devise-passkeys/blob/main/CODE_OF_CONDUCT.md).
194
195
 
195
196
 
196
197
  ## Acknowledgements
data/THANKS.md ADDED
@@ -0,0 +1,9 @@
1
+ # Thanks to everyone's who's contributed or helped out!
2
+
3
+ ## Contributors
4
+
5
+ - [@heliocola](https://github.com/heliocola)
6
+ - [@JanaganSaravanan](https://github.com/JanaganSaravanan)
7
+ - [@johalloran01](https://github.com/johalloran01)
8
+ - [@tcannonfodder](https://github.com/tcannonfodder)
9
+ - [@Vagab](https://github.com/Vagab)
@@ -32,8 +32,8 @@ Gem::Specification.new do |spec|
32
32
  spec.require_paths = ["lib"]
33
33
 
34
34
  # Uncomment to register a new dependency of your gem
35
- spec.add_dependency "devise"
36
- spec.add_dependency "warden-webauthn", ">= 0.2.0"
35
+ spec.add_dependency "devise", ">= 4.7.1"
36
+ spec.add_dependency "warden-webauthn", ">= 0.3.0"
37
37
 
38
38
  # For more information and examples about making a new gem, check out our
39
39
  # guide at: https://bundler.io/guides/creating_gem.html
@@ -10,6 +10,8 @@ group :development, :test do
10
10
  gem "debug"
11
11
  gem "rake", "~> 13.0"
12
12
  gem "rubocop", "~> 1.21"
13
+ gem "yard"
14
+ gem "webrick"
13
15
  end
14
16
 
15
17
  group :test do
@@ -10,6 +10,8 @@ group :development, :test do
10
10
  gem "debug"
11
11
  gem "rake", "~> 13.0"
12
12
  gem "rubocop", "~> 1.21"
13
+ gem "yard"
14
+ gem "webrick"
13
15
  end
14
16
 
15
17
  group :test do
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Devise
4
+ module Passkeys
5
+ module Controllers
6
+ module Concerns
7
+ # This concern is responsible for storing, retrieving, clearing, consuming,
8
+ # and validating the reauthentication token in the session.
9
+ #
10
+ # A reauthentication token is a one-time random value that is used to
11
+ # indicate that the user has successfully been reauthenticated. This can be
12
+ # used for scenarios such as:
13
+ #
14
+ # - Adding a new passkey
15
+ # - Deleting a passkey
16
+ # - Performing sensitive actions inside your application
17
+ #
18
+ # You can customize which reauthentication token you're using by changing
19
+ # the `passkey_reauthentication_token_key` method after including this concern
20
+ #
21
+ # @see Devise::Passkeys::Controllers::ReauthenticationControllerConcern
22
+ module Reauthentication
23
+ extend ActiveSupport::Concern
24
+
25
+ # This method is responsible for storing the reauthentication token
26
+ # in the session.
27
+ #
28
+ # The reauthentication token is securely generated using `Devise.friendly_token`
29
+ #
30
+ # @return [String] The reauthentication token
31
+ # @see passkey_reauthentication_token_key
32
+ def store_reauthentication_token_in_session
33
+ session[passkey_reauthentication_token_key] = Devise.friendly_token(50)
34
+ end
35
+
36
+ # This method is responsible for retrieving the reauthentication token
37
+ # from the session.
38
+ #
39
+ # @return [String] The reauthentication token
40
+ # @see passkey_reauthentication_token_key
41
+ # @see store_reauthentication_token_in_session
42
+ def stored_reauthentication_token
43
+ session[passkey_reauthentication_token_key]
44
+ end
45
+
46
+ # This method is responsible for clearing the reauthentication token from
47
+ # the session.
48
+ #
49
+ # @return [String] The reauthentication token
50
+ # @see passkey_reauthentication_token_key
51
+ def clear_reauthentication_token!
52
+ session.delete(passkey_reauthentication_token_key)
53
+ end
54
+
55
+ # This method is responsible for consuming (i.e. retrieving & clearing)
56
+ # the reauthentication token from the session.
57
+ #
58
+ # @return [String] The reauthentication token
59
+ # @see stored_reauthentication_token
60
+ # @see clear_reauthentication_token!
61
+ def consume_reauthentication_token!
62
+ value = stored_reauthentication_token
63
+ clear_reauthentication_token!
64
+ value
65
+ end
66
+
67
+ # This method is responsible for validating the given reauthentication token
68
+ # against the one currently in the session.
69
+ #
70
+ # **Note**: Whenever a reauthentication token is checked using `valid_reauthentication_token?`,
71
+ # It will be consumed. This means that a new token will need to be generated & stored
72
+ # (by reauthenticating the user) if there were any issues.
73
+ #
74
+ # @param [String] given_reauthentication_token token to compare store token against
75
+ # @return [Boolean] whether the `given_reauthentication_token` is the same as the
76
+ # `stored_reauthentication_token`
77
+ # @see consume_reauthentication_token!
78
+ def valid_reauthentication_token?(given_reauthentication_token:)
79
+ Devise.secure_compare(consume_reauthentication_token!, given_reauthentication_token)
80
+ end
81
+
82
+ # This method is responsible for generating the key that will be used
83
+ # to store the reauthentication token in the session hash.
84
+ #
85
+ # @return [String] The key that will be used to access the reauthentication token in the session
86
+ def passkey_reauthentication_token_key
87
+ "#{resource_name}_current_reauthentication_token"
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -4,13 +4,39 @@ module Devise
4
4
  module Passkeys
5
5
  module Controllers
6
6
  module Concerns
7
+ # This concern is responsible for storing the reauthentication challenge in the session.
8
+ #
9
+ # A reauthentication challenge is a WebAuthn challenge exchange (i.e. authentication)
10
+ # to verify the user's identity and confirm they're able to perform a sensitive action
11
+ # by performing the entire authentication process.
12
+ #
13
+ # This can be used for scenarios such as:
14
+ #
15
+ # - Adding a new passkey
16
+ # - Deleting a passkey
17
+ # - Performing sensitive actions inside your application
18
+ #
19
+ # You can customize which reauthentication challenge you're using by changing
20
+ # the `passkey_reauthentication_challenge_session_key` method after including this concern
21
+ #
22
+ # @see Devise::Passkeys::Controllers::ReauthenticationControllerConcern
7
23
  module ReauthenticationChallenge
8
24
  extend ActiveSupport::Concern
9
25
 
26
+ # This method is responsible for generating the key that will be used to store the
27
+ # reauthentication challenge in the session hash.
28
+ #
29
+ # @return [String] The reauthentication challenge session key
10
30
  def passkey_reauthentication_challenge_session_key
11
31
  "#{resource_name}_current_reauthentication_challenge"
12
32
  end
13
33
 
34
+ # This method is responsible for storing the reauthentication challenge in the session.
35
+ #
36
+ # @param [WebAuthn::PublicKeyCredential::RequestOptions] options_for_authentication the options for authentication,
37
+ # generated by `webauthn-ruby`
38
+ # @return [String] The reauthentication challenge
39
+ # @see Devise::Passkeys::Controllers::ReauthenticationControllerConcern#new_challenge
14
40
  def store_reauthentication_challenge_in_session(options_for_authentication:)
15
41
  session[passkey_reauthentication_challenge_session_key] = options_for_authentication.challenge
16
42
  end