devise-webauthn 0.2.0 → 0.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/.github/FUNDING.yml +1 -0
- data/.github/workflows/release.yml +28 -0
- data/.github/workflows/ruby.yml +7 -0
- data/Appraisals +4 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +1 -1
- data/README.md +24 -5
- data/app/controllers/devise/second_factor_webauthn_credentials_controller.rb +1 -16
- data/app/controllers/devise/two_factor_authentications_controller.rb +1 -7
- data/app/views/devise/second_factor_webauthn_credentials/new.html.erb +1 -11
- data/app/views/devise/two_factor_authentications/new.html.erb +1 -12
- data/config/locales/en.yml +0 -1
- data/gemfiles/rails_8_1.gemfile +21 -0
- data/lib/devise/strategies/database_authenticatable.rb +5 -1
- data/lib/devise/webauthn/helpers/credentials_helper.rb +82 -4
- data/lib/devise/webauthn/version.rb +1 -1
- metadata +6 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8083a823cce7edf858475a062ea009193c3a86cf9b4a821db1dd2715430580d4
|
|
4
|
+
data.tar.gz: df00de569113a642c13f87cc4f6c93836acb5c5df1ef1cecfe492b01247a17aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ce764390d121fc68bd1732d655700ccae382ced384a24f350256f2bb633910d0038972637a8e9f4f5e512d0e13030c53851f7288733fb233e8d86fe00ab5c8b8
|
|
7
|
+
data.tar.gz: d2072d245253437be40005c81b9879f22f0a7c0fa3e0e3cd39b9b03f812aa05cdcd7404cbd4123afac473785364472f3e025dbdf025ae3f74af117854dcbca38
|
data/.github/FUNDING.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
github: [cedarcode]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
release:
|
|
9
|
+
name: Publish to Rubygems
|
|
10
|
+
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
environment: release
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
id-token: write
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v6
|
|
21
|
+
|
|
22
|
+
- name: Setup Ruby
|
|
23
|
+
uses: ruby/setup-ruby@v1
|
|
24
|
+
with:
|
|
25
|
+
bundler-cache: true
|
|
26
|
+
|
|
27
|
+
- name: Publish to RubyGems
|
|
28
|
+
uses: rubygems/release-gem@v1
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -32,6 +32,7 @@ jobs:
|
|
|
32
32
|
- 2.7
|
|
33
33
|
gemfile:
|
|
34
34
|
- rails_edge
|
|
35
|
+
- rails_8_1
|
|
35
36
|
- rails_8_0
|
|
36
37
|
- rails_7_2
|
|
37
38
|
- rails_7_1
|
|
@@ -39,11 +40,15 @@ jobs:
|
|
|
39
40
|
exclude:
|
|
40
41
|
- ruby: 3.1
|
|
41
42
|
gemfile: rails_edge
|
|
43
|
+
- ruby: 3.1
|
|
44
|
+
gemfile: rails_8_1
|
|
42
45
|
- ruby: 3.1
|
|
43
46
|
gemfile: rails_8_0
|
|
44
47
|
|
|
45
48
|
- ruby: 3.0
|
|
46
49
|
gemfile: rails_edge
|
|
50
|
+
- ruby: 3.0
|
|
51
|
+
gemfile: rails_8_1
|
|
47
52
|
- ruby: 3.0
|
|
48
53
|
gemfile: rails_8_0
|
|
49
54
|
- ruby: 3.0
|
|
@@ -51,6 +56,8 @@ jobs:
|
|
|
51
56
|
|
|
52
57
|
- ruby: 2.7
|
|
53
58
|
gemfile: rails_edge
|
|
59
|
+
- ruby: 2.7
|
|
60
|
+
gemfile: rails_8_1
|
|
54
61
|
- ruby: 2.7
|
|
55
62
|
gemfile: rails_8_0
|
|
56
63
|
- ruby: 2.7
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## [v0.2.1](https://github.com/cedarcode/devise-webauthn/compare/v0.2.0...v0.2.1/) - 2025-12-10
|
|
6
|
+
|
|
7
|
+
- Add form helpers for security key registration and 2FA authentication.
|
|
8
|
+
- Fix incorrect call to `resource_name` instead of using passed `resource` param in `login_with_security_key_button` helper.
|
|
9
|
+
- Fix `NoMethodError` when calling `second_factor_enabled?` on resources without 2FA.
|
|
10
|
+
- Avoid assuming `email` as the authentication key of the resource in form helpers.
|
|
11
|
+
|
|
5
12
|
## [v0.2.0](https://github.com/cedarcode/devise-webauthn/compare/v0.1.2...v0.2.0/) - 2025-12-03
|
|
6
13
|
|
|
7
14
|
- Add new `webauthn_two_factor_authenticatable` module for enabling 2FA using WebAuthn credentials.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Devise::Webauthn
|
|
2
2
|
[](https://badge.fury.io/rb/devise-webauthn)
|
|
3
3
|
|
|
4
|
-
Devise::Webauthn is a [Devise](https://github.com/heartcombo/devise) extension that adds [WebAuthn](https://www.w3.org/TR/2025/WD-webauthn-3-20250127/) support to your Rails application, allowing users to authenticate with [passkeys](https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#passkey).
|
|
4
|
+
Devise::Webauthn is a [Devise](https://github.com/heartcombo/devise) extension that adds [WebAuthn](https://www.w3.org/TR/2025/WD-webauthn-3-20250127/) support to your Rails application, allowing users to authenticate with [passkeys](https://www.w3.org/TR/2025/WD-webauthn-3-20250127/#passkey) and use [security keys](https://www.w3.org/TR/webauthn-3/#server-side-credential) for two factor authentication.
|
|
5
5
|
|
|
6
6
|
## Requirements
|
|
7
7
|
|
|
@@ -54,11 +54,12 @@ Then, follow these steps to integrate Devise::Webauthn:
|
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
3. **Update Your Devise Model:**
|
|
57
|
-
Add `:passkey_authenticatable` to your Devise model (e.g., `User`):
|
|
57
|
+
Add `:passkey_authenticatable` to your Devise model (e.g., `User`) for passkeys authentication and `:webauthn_two_factor_authenticatable` for WebAuthn-based 2FA if desired. For example:
|
|
58
58
|
```ruby
|
|
59
59
|
class User < ApplicationRecord
|
|
60
60
|
devise :database_authenticatable, :registerable,
|
|
61
|
-
:recoverable, :rememberable, :validatable,
|
|
61
|
+
:recoverable, :rememberable, :validatable,
|
|
62
|
+
:passkey_authenticatable, :webauthn_two_factor_authenticatable
|
|
62
63
|
end
|
|
63
64
|
```
|
|
64
65
|
|
|
@@ -77,10 +78,12 @@ Then, follow these steps to integrate Devise::Webauthn:
|
|
|
77
78
|
|
|
78
79
|
## How It Works
|
|
79
80
|
|
|
80
|
-
###
|
|
81
|
+
### Passkey authentication
|
|
82
|
+
|
|
83
|
+
#### Adding Passkeys
|
|
81
84
|
Signed-in users can add passkeys by visiting `/users/passkeys/new`.
|
|
82
85
|
|
|
83
|
-
|
|
86
|
+
#### Sign In with Passkeys
|
|
84
87
|
When a user visits `/users/sign_in` they can choose to authenticate using a passkey. The authentication flow is handled by `PasskeysAuthenticatable` strategy.
|
|
85
88
|
|
|
86
89
|
The WebAuthn passkey sign-in flow works as follows:
|
|
@@ -89,6 +92,22 @@ The WebAuthn passkey sign-in flow works as follows:
|
|
|
89
92
|
3. User selects a passkey and verifies with their [authenticator](https://www.w3.org/TR/webauthn-3/#webauthn-authenticator).
|
|
90
93
|
4. The server verifies the response and signs in the user.
|
|
91
94
|
|
|
95
|
+
### Two-Factor Authentication (2FA) with WebAuthn
|
|
96
|
+
|
|
97
|
+
#### Adding Security Keys for 2FA
|
|
98
|
+
Signed-in users can add security keys by visiting `/users/second_factor_webauthn_credentials/new`.
|
|
99
|
+
|
|
100
|
+
#### 2FA Sign In with Security Keys
|
|
101
|
+
When a user that has 2FA enabled (i.e., has registered passkeys or security keys) visits `/users/sign_in`, after entering their primary credentials (e.g., email and password), they will be prompted to complete the second factor authentication using WebAuthn. The authentication flow is handled by `WebauthnTwoFactorAuthenticatable` strategy.
|
|
102
|
+
|
|
103
|
+
The two factor authentication flow with WebAuthn works as follows:
|
|
104
|
+
1. User enters their primary credentials (e.g., email and password) and submits the form.
|
|
105
|
+
2. If the user has 2FA enabled, they are redirected to a second factor authentication page.
|
|
106
|
+
3. User clicks "Use security key", starting a WebAuthn authentication ceremony.
|
|
107
|
+
4. Browser shows available credentials (which can be both passkeys and security keys).
|
|
108
|
+
5. User selects a credential and verifies with their [authenticator](https://www.w3.org/TR/webauthn-3/#webauthn-authenticator).
|
|
109
|
+
6. The server verifies the response and signs in the user.
|
|
110
|
+
|
|
92
111
|
## Customization
|
|
93
112
|
|
|
94
113
|
### Customizing Views
|
|
@@ -4,22 +4,7 @@ module Devise
|
|
|
4
4
|
class SecondFactorWebauthnCredentialsController < DeviseController
|
|
5
5
|
before_action :authenticate_scope!
|
|
6
6
|
|
|
7
|
-
def new
|
|
8
|
-
@options = WebAuthn::Credential.options_for_create(
|
|
9
|
-
user: {
|
|
10
|
-
id: resource.webauthn_id,
|
|
11
|
-
name: resource.email
|
|
12
|
-
},
|
|
13
|
-
exclude: resource.webauthn_credentials.pluck(:external_id),
|
|
14
|
-
authenticator_selection: {
|
|
15
|
-
resident_key: "discouraged",
|
|
16
|
-
user_verification: "discouraged"
|
|
17
|
-
}
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
# Store challenge in session for later verification
|
|
21
|
-
session[:webauthn_challenge] = @options.challenge
|
|
22
|
-
end
|
|
7
|
+
def new; end
|
|
23
8
|
|
|
24
9
|
def create
|
|
25
10
|
security_key_from_params = WebAuthn::Credential.from_create(JSON.parse(params[:public_key_credential]))
|
|
@@ -6,13 +6,7 @@ module Devise
|
|
|
6
6
|
prepend_before_action :ensure_sign_in_initiated
|
|
7
7
|
prepend_before_action :require_no_authentication
|
|
8
8
|
|
|
9
|
-
def new
|
|
10
|
-
@options = WebAuthn::Credential.options_for_get(
|
|
11
|
-
allow: @resource.webauthn_credentials.pluck(:external_id),
|
|
12
|
-
user_verification: "discouraged"
|
|
13
|
-
)
|
|
14
|
-
session[:two_factor_authentication_challenge] = @options.challenge
|
|
15
|
-
end
|
|
9
|
+
def new; end
|
|
16
10
|
|
|
17
11
|
def create
|
|
18
12
|
self.resource = warden.authenticate!(auth_options)
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
<%=
|
|
2
|
-
url: second_factor_webauthn_credentials_path(resource),
|
|
3
|
-
method: :post,
|
|
4
|
-
data: {
|
|
5
|
-
action: "webauthn-credentials#create:prevent",
|
|
6
|
-
controller: "webauthn-credentials",
|
|
7
|
-
webauthn_credentials_options_param: @options,
|
|
8
|
-
}
|
|
9
|
-
) do |form| %>
|
|
10
|
-
<%= form.hidden_field(:public_key_credential,
|
|
11
|
-
data: { "webauthn-credentials-target": "credentialHiddenInput" }) %>
|
|
1
|
+
<%= security_key_creation_form_for(resource) do |form| %>
|
|
12
2
|
<%= form.label :name, 'Security Key name' %>
|
|
13
3
|
<%= form.text_field :name, required: true %>
|
|
14
4
|
<%= form.submit 'Create Security Key' %>
|
|
@@ -1,12 +1 @@
|
|
|
1
|
-
<%=
|
|
2
|
-
url: two_factor_authentication_path(resource_name),
|
|
3
|
-
method: :post,
|
|
4
|
-
data: {
|
|
5
|
-
action: "webauthn-credentials#get:prevent",
|
|
6
|
-
controller: "webauthn-credentials",
|
|
7
|
-
webauthn_credentials_options_param: @options
|
|
8
|
-
},
|
|
9
|
-
) do |f| %>
|
|
10
|
-
<%= f.hidden_field(:public_key_credential, data: { "webauthn-credentials-target": "credentialHiddenInput" }) %>
|
|
11
|
-
<%= f.button('Use security key', type: "submit") %>
|
|
12
|
-
<% end %>
|
|
1
|
+
<%= login_with_security_key_button('Use security key', resource: @resource) %>
|
data/config/locales/en.yml
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "appraisal", "~> 2.5"
|
|
6
|
+
gem "capybara", "~> 3.40"
|
|
7
|
+
gem "combustion", "~> 1.3"
|
|
8
|
+
gem "importmap-rails", "~> 2.2"
|
|
9
|
+
gem "propshaft", "~> 1.2"
|
|
10
|
+
gem "pry-byebug", "~> 3.11"
|
|
11
|
+
gem "puma", "~> 6.6"
|
|
12
|
+
gem "rails", "~> 8.1"
|
|
13
|
+
gem "rspec-rails", "~> 8.0"
|
|
14
|
+
gem "rubocop", "~> 1.79"
|
|
15
|
+
gem "rubocop-rails", "~> 2.32"
|
|
16
|
+
gem "rubocop-rspec", "~> 3.6"
|
|
17
|
+
gem "selenium-webdriver"
|
|
18
|
+
gem "sqlite3", "~> 2.7"
|
|
19
|
+
gem "stimulus-rails", "~> 1.3"
|
|
20
|
+
|
|
21
|
+
gemspec path: "../"
|
|
@@ -11,7 +11,7 @@ module Devise
|
|
|
11
11
|
hashed = false
|
|
12
12
|
|
|
13
13
|
if validate(resource){ hashed = true; resource.valid_password?(password) }
|
|
14
|
-
if
|
|
14
|
+
if second_factor_enabled?(resource)
|
|
15
15
|
session[:current_authentication_resource_id] = resource.id
|
|
16
16
|
request.flash[:notice] = two_factor_required_message
|
|
17
17
|
request.commit_flash
|
|
@@ -41,6 +41,10 @@ module Devise
|
|
|
41
41
|
def two_factor_required_message
|
|
42
42
|
I18n.t(:"#{scope}.two_factor_required", resource_name: scope, scope: "devise.failure", default: :two_factor_required)
|
|
43
43
|
end
|
|
44
|
+
|
|
45
|
+
def second_factor_enabled?(resource)
|
|
46
|
+
resource.respond_to?(:second_factor_enabled?) && resource.second_factor_enabled?
|
|
47
|
+
end
|
|
44
48
|
end
|
|
45
49
|
end
|
|
46
50
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# rubocop:disable Metrics/ModuleLength
|
|
3
4
|
module Devise
|
|
4
5
|
module Webauthn
|
|
5
6
|
module CredentialsHelper
|
|
@@ -27,7 +28,41 @@ module Devise
|
|
|
27
28
|
data: {
|
|
28
29
|
action: "webauthn-credentials#get:prevent",
|
|
29
30
|
controller: "webauthn-credentials",
|
|
30
|
-
webauthn_credentials_options_param:
|
|
31
|
+
webauthn_credentials_options_param: passkey_authentication_options
|
|
32
|
+
},
|
|
33
|
+
class: form_classes
|
|
34
|
+
) do |f|
|
|
35
|
+
concat f.hidden_field(:public_key_credential,
|
|
36
|
+
data: { "webauthn-credentials-target": "credentialHiddenInput" })
|
|
37
|
+
concat f.button(text, type: "submit", class: button_classes, &block)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def security_key_creation_form_for(resource, form_classes: nil, &block)
|
|
42
|
+
form_with(
|
|
43
|
+
url: second_factor_webauthn_credentials_path(resource),
|
|
44
|
+
method: :post,
|
|
45
|
+
class: form_classes,
|
|
46
|
+
data: {
|
|
47
|
+
action: "webauthn-credentials#create:prevent",
|
|
48
|
+
controller: "webauthn-credentials",
|
|
49
|
+
webauthn_credentials_options_param: create_security_key_options(resource)
|
|
50
|
+
}
|
|
51
|
+
) do |f|
|
|
52
|
+
concat f.hidden_field(:public_key_credential,
|
|
53
|
+
data: { "webauthn-credentials-target": "credentialHiddenInput" })
|
|
54
|
+
concat capture(f, &block)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def login_with_security_key_button(text = nil, resource:, button_classes: nil, form_classes: nil, &block)
|
|
59
|
+
form_with(
|
|
60
|
+
url: two_factor_authentication_path(resource),
|
|
61
|
+
method: :post,
|
|
62
|
+
data: {
|
|
63
|
+
action: "webauthn-credentials#get:prevent",
|
|
64
|
+
controller: "webauthn-credentials",
|
|
65
|
+
webauthn_credentials_options_param: security_key_authentication_options(resource)
|
|
31
66
|
},
|
|
32
67
|
class: form_classes
|
|
33
68
|
) do |f|
|
|
@@ -44,7 +79,7 @@ module Devise
|
|
|
44
79
|
options = WebAuthn::Credential.options_for_create(
|
|
45
80
|
user: {
|
|
46
81
|
id: resource.webauthn_id,
|
|
47
|
-
name:
|
|
82
|
+
name: resource_human_palatable_identifier
|
|
48
83
|
},
|
|
49
84
|
exclude: resource.passkeys.pluck(:external_id),
|
|
50
85
|
authenticator_selection: {
|
|
@@ -60,8 +95,8 @@ module Devise
|
|
|
60
95
|
end
|
|
61
96
|
end
|
|
62
97
|
|
|
63
|
-
def
|
|
64
|
-
@
|
|
98
|
+
def passkey_authentication_options
|
|
99
|
+
@passkey_authentication_options ||= begin
|
|
65
100
|
options = WebAuthn::Credential.options_for_get(
|
|
66
101
|
user_verification: "required"
|
|
67
102
|
)
|
|
@@ -72,6 +107,49 @@ module Devise
|
|
|
72
107
|
options
|
|
73
108
|
end
|
|
74
109
|
end
|
|
110
|
+
|
|
111
|
+
def create_security_key_options(resource)
|
|
112
|
+
@create_security_key_options ||= begin
|
|
113
|
+
options = WebAuthn::Credential.options_for_create(
|
|
114
|
+
user: {
|
|
115
|
+
id: resource.webauthn_id,
|
|
116
|
+
name: resource_human_palatable_identifier
|
|
117
|
+
},
|
|
118
|
+
exclude: resource.webauthn_credentials.pluck(:external_id),
|
|
119
|
+
authenticator_selection: {
|
|
120
|
+
resident_key: "discouraged",
|
|
121
|
+
user_verification: "discouraged"
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Store challenge in session for later verification
|
|
126
|
+
session[:webauthn_challenge] = options.challenge
|
|
127
|
+
|
|
128
|
+
options
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def security_key_authentication_options(resource)
|
|
133
|
+
@security_key_authentication_options ||= begin
|
|
134
|
+
options = WebAuthn::Credential.options_for_get(
|
|
135
|
+
allow: resource.webauthn_credentials.pluck(:external_id),
|
|
136
|
+
user_verification: "discouraged"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Store challenge in session for later verification
|
|
140
|
+
session[:two_factor_authentication_challenge] = options.challenge
|
|
141
|
+
|
|
142
|
+
options
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def resource_human_palatable_identifier
|
|
147
|
+
authentication_keys = resource.class.authentication_keys
|
|
148
|
+
authentication_keys = authentication_keys.keys if authentication_keys.is_a?(Hash)
|
|
149
|
+
|
|
150
|
+
authentication_keys.filter_map { |authentication_key| resource.public_send(authentication_key) }.first
|
|
151
|
+
end
|
|
75
152
|
end
|
|
76
153
|
end
|
|
77
154
|
end
|
|
155
|
+
# rubocop:enable Metrics/ModuleLength
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: devise-webauthn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cedarcode
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: devise
|
|
@@ -38,13 +37,14 @@ dependencies:
|
|
|
38
37
|
- - "~>"
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
39
|
version: '3.0'
|
|
41
|
-
description:
|
|
42
40
|
email:
|
|
43
41
|
- webauthn@cedarcode.com
|
|
44
42
|
executables: []
|
|
45
43
|
extensions: []
|
|
46
44
|
extra_rdoc_files: []
|
|
47
45
|
files:
|
|
46
|
+
- ".github/FUNDING.yml"
|
|
47
|
+
- ".github/workflows/release.yml"
|
|
48
48
|
- ".github/workflows/ruby.yml"
|
|
49
49
|
- ".gitignore"
|
|
50
50
|
- ".rspec"
|
|
@@ -73,6 +73,7 @@ files:
|
|
|
73
73
|
- gemfiles/rails_7_1.gemfile
|
|
74
74
|
- gemfiles/rails_7_2.gemfile
|
|
75
75
|
- gemfiles/rails_8_0.gemfile
|
|
76
|
+
- gemfiles/rails_8_1.gemfile
|
|
76
77
|
- gemfiles/rails_edge.gemfile
|
|
77
78
|
- lib/devise/models/passkey_authenticatable.rb
|
|
78
79
|
- lib/devise/models/webauthn_credential_authenticatable.rb
|
|
@@ -105,7 +106,6 @@ metadata:
|
|
|
105
106
|
source_code_uri: https://github.com/cedarcode/devise-webauthn
|
|
106
107
|
changelog_uri: https://github.com/cedarcode/devise-webauthn/blob/master/CHANGELOG.md
|
|
107
108
|
rubygems_mfa_required: 'true'
|
|
108
|
-
post_install_message:
|
|
109
109
|
rdoc_options: []
|
|
110
110
|
require_paths:
|
|
111
111
|
- lib
|
|
@@ -120,8 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
120
120
|
- !ruby/object:Gem::Version
|
|
121
121
|
version: '0'
|
|
122
122
|
requirements: []
|
|
123
|
-
rubygems_version: 3.
|
|
124
|
-
signing_key:
|
|
123
|
+
rubygems_version: 3.6.7
|
|
125
124
|
specification_version: 4
|
|
126
125
|
summary: Devise extension to support WebAuthn.
|
|
127
126
|
test_files: []
|