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 +4 -4
- data/.yardopts +1 -0
- data/CHANGELOG.md +47 -2
- data/CONTRIBUTING.md +47 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +90 -38
- data/README.md +24 -23
- data/THANKS.md +9 -0
- data/devise-passkeys.gemspec +2 -2
- data/gemfiles/rails_6.gemfile +2 -0
- data/gemfiles/rails_7.gemfile +2 -0
- data/lib/devise/passkeys/controllers/concerns/reauthentication.rb +93 -0
- data/lib/devise/passkeys/controllers/concerns/reauthentication_challenge.rb +26 -0
- data/lib/devise/passkeys/controllers/passkeys_controller_concern.rb +18 -13
- data/lib/devise/passkeys/controllers/reauthentication_controller_concern.rb +70 -4
- data/lib/devise/passkeys/controllers/registrations_controller_concern.rb +146 -7
- data/lib/devise/passkeys/controllers/sessions_controller_concern.rb +3 -3
- data/lib/devise/passkeys/controllers.rb +55 -1
- data/lib/devise/passkeys/model.rb +9 -1
- data/lib/devise/passkeys/passkey_issuer.rb +0 -2
- data/lib/devise/passkeys/reauthentication_strategy.rb +7 -0
- data/lib/devise/passkeys/strategy.rb +1 -1
- data/lib/devise/passkeys/version.rb +1 -1
- data/lib/devise/passkeys.rb +22 -5
- metadata +10 -7
- data/lib/devise/passkeys/controllers/concerns/passkey_reauthentication.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66ad22c45235ff6c913652a436ce925edca3a8088d657b4ab98d8a2ed57dd863
|
4
|
+
data.tar.gz: 718f3ac80d832c87246a7e4abbf868d41fe1b94a402ebb4869fe873aab374bc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
## [
|
1
|
+
## [0.3.0] - 2023-08-18
|
2
2
|
|
3
|
-
|
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
data/Gemfile.lock
CHANGED
@@ -1,19 +1,32 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
devise-passkeys (0.
|
5
|
-
devise
|
6
|
-
warden-webauthn (>= 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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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.
|
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.
|
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.
|
58
|
+
debug (1.8.0)
|
46
59
|
irb (>= 1.5.0)
|
47
60
|
reline (>= 0.3.1)
|
48
|
-
devise (
|
49
|
-
bcrypt
|
50
|
-
orm_adapter (~> 0.
|
51
|
-
|
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
|
-
|
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.
|
72
|
+
irb (1.7.1)
|
57
73
|
reline (>= 0.3.0)
|
58
74
|
json (2.6.3)
|
59
|
-
jwt (2.7.
|
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.
|
84
|
+
minitest (5.18.1)
|
65
85
|
minitest-ci (3.4.0)
|
66
86
|
minitest (>= 5.0.6)
|
67
|
-
mongo (2.
|
87
|
+
mongo (2.19.0)
|
68
88
|
bson (>= 4.14.1, < 5.0.0)
|
69
|
-
mongoid (8.0
|
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
|
77
|
-
parallel (1.
|
78
|
-
parser (3.2.
|
101
|
+
orm_adapter (0.5.0)
|
102
|
+
parallel (1.23.0)
|
103
|
+
parser (3.2.2.3)
|
79
104
|
ast (~> 2.4.1)
|
80
|
-
|
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.
|
84
|
-
reline (0.3.
|
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.
|
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.
|
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.
|
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.
|
144
|
+
rubocop-ast (1.29.0)
|
98
145
|
parser (>= 3.2.1.0)
|
99
|
-
ruby-progressbar (1.
|
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.
|
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.
|
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.
|
203
|
+
2.4.12
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ $ bundle
|
|
19
19
|
|
20
20
|
# Usage
|
21
21
|
|
22
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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/
|
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/
|
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)
|
data/devise-passkeys.gemspec
CHANGED
@@ -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.
|
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
|
data/gemfiles/rails_6.gemfile
CHANGED
data/gemfiles/rails_7.gemfile
CHANGED
@@ -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
|