devise-webauthn 0.2.1 → 0.2.2
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/dependabot.yml +6 -0
- data/.github/workflows/ruby.yml +2 -2
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/app/controllers/devise/passkeys_controller.rb +6 -1
- data/app/controllers/devise/second_factor_webauthn_credentials_controller.rb +6 -1
- data/config/locales/en.yml +4 -0
- data/lib/devise/webauthn/test/authenticator_helpers.rb +42 -0
- data/lib/devise/webauthn/version.rb +1 -1
- data/lib/generators/devise/webauthn/controllers_generator.rb +5 -1
- data/lib/generators/devise/webauthn/templates/controllers/second_factor_webauthn_credentials_controller.rb.tt +31 -0
- data/lib/generators/devise/webauthn/templates/controllers/two_factor_authentications_controller.rb.tt +13 -0
- data/lib/generators/devise/webauthn/views_generator.rb +2 -0
- data/lib/generators/devise/webauthn/webauthn_credential_model/templates/webauthn_credential_migration.rb.erb +17 -0
- data/lib/generators/devise/webauthn/webauthn_credential_model/webauthn_credential_model_generator.rb +15 -9
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bf586d5c54c83dcd4dd18c38e2dfe2c8d16cd86dc90e3c5c09b516d3c60dff04
|
|
4
|
+
data.tar.gz: 5a56dc38f1bd836b69dae7057f44ba95868b1edbfe5820eab77466ec2db59ffd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c62d4d71fd255dbf5867c76a524ed2b8e22df167e537e52a928f5a88351291ccb4cc74aef5e0466b27c42242d6b0ab105e67acc2ba9d7cb673625ff0b31100b4
|
|
7
|
+
data.tar.gz: fefeab5ad1470d5a2eb3f451c823763f237c8fe3f302f46d02917bbf337a0ab3011fc518b209d6105aed7ca23c21cb8ef9621f360a6a980204d3fe28508cf552
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -8,7 +8,7 @@ jobs:
|
|
|
8
8
|
|
|
9
9
|
steps:
|
|
10
10
|
- name: Check out repository code
|
|
11
|
-
uses: actions/checkout@
|
|
11
|
+
uses: actions/checkout@v6
|
|
12
12
|
|
|
13
13
|
- name: Set up Ruby
|
|
14
14
|
uses: ruby/setup-ruby@v1
|
|
@@ -69,7 +69,7 @@ jobs:
|
|
|
69
69
|
|
|
70
70
|
steps:
|
|
71
71
|
- name: Check out repository code
|
|
72
|
-
uses: actions/checkout@
|
|
72
|
+
uses: actions/checkout@v6
|
|
73
73
|
|
|
74
74
|
- name: Set up Ruby
|
|
75
75
|
uses: ruby/setup-ruby@v1
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## [v0.2.2](https://github.com/cedarcode/devise-webauthn/compare/v0.2.1...v0.2.2/) - 2025-12-11
|
|
6
|
+
|
|
7
|
+
- Generate webauthn credentials table with not null constraints in attributes that must be present.
|
|
8
|
+
- Update controllers and views generators to generate 2FA-related controllers and views.
|
|
9
|
+
- Add flash messages when removing credentials.
|
|
10
|
+
|
|
5
11
|
## [v0.2.1](https://github.com/cedarcode/devise-webauthn/compare/v0.2.0...v0.2.1/) - 2025-12-10
|
|
6
12
|
|
|
7
13
|
- Add form helpers for security key registration and 2FA authentication.
|
data/Gemfile.lock
CHANGED
|
@@ -23,7 +23,12 @@ module Devise
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def destroy
|
|
26
|
-
resource.passkeys.destroy(params[:id])
|
|
26
|
+
if resource.passkeys.destroy(params[:id])
|
|
27
|
+
set_flash_message! :notice, :passkey_deleted
|
|
28
|
+
else
|
|
29
|
+
set_flash_message! :alert, :passkey_deletion_failed, scope: :"devise.failure"
|
|
30
|
+
end
|
|
31
|
+
|
|
27
32
|
redirect_to after_update_path
|
|
28
33
|
end
|
|
29
34
|
|
|
@@ -23,7 +23,12 @@ module Devise
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def destroy
|
|
26
|
-
resource.second_factor_webauthn_credentials.destroy(params[:id])
|
|
26
|
+
if resource.second_factor_webauthn_credentials.destroy(params[:id])
|
|
27
|
+
set_flash_message! :notice, :security_key_deleted
|
|
28
|
+
else
|
|
29
|
+
set_flash_message! :alert, :security_key_deletion_failed, scope: :"devise.failure"
|
|
30
|
+
end
|
|
31
|
+
|
|
27
32
|
redirect_to after_update_path
|
|
28
33
|
end
|
|
29
34
|
|
data/config/locales/en.yml
CHANGED
|
@@ -2,11 +2,15 @@ en:
|
|
|
2
2
|
devise:
|
|
3
3
|
passkeys:
|
|
4
4
|
passkey_created: "Passkey created successfully."
|
|
5
|
+
passkey_deleted: "Passkey deleted successfully."
|
|
5
6
|
second_factor_webauthn_credentials:
|
|
6
7
|
security_key_created: "Security Key created successfully."
|
|
8
|
+
security_key_deleted: "Security Key deleted successfully."
|
|
7
9
|
failure:
|
|
8
10
|
passkey_not_found: "Your passkey doesn't exist or is not valid."
|
|
9
11
|
passkey_verification_failed: "Passkey verification failed."
|
|
12
|
+
passkey_deletion_failed: "Passkey deletion failed."
|
|
13
|
+
security_key_deletion_failed: "Security Key deletion failed."
|
|
10
14
|
sign_in_not_initiated: "Sign in was not initiated."
|
|
11
15
|
two_factor_required: "Two-factor authentication is required to sign in."
|
|
12
16
|
webauthn_credential_not_found: "Your WebAuthn credential doesn't exist or is not valid."
|
|
@@ -11,6 +11,48 @@ module Devise
|
|
|
11
11
|
options.resident_key = true
|
|
12
12
|
page.driver.browser.add_virtual_authenticator(options)
|
|
13
13
|
end
|
|
14
|
+
|
|
15
|
+
def add_passkey_to_authenticator(authenticator, resource)
|
|
16
|
+
add_credential_to_authenticator(authenticator, resource, passkey: true)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def add_security_key_to_authenticator(authenticator, resource)
|
|
20
|
+
add_credential_to_authenticator(authenticator, resource, passkey: false)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# rubocop:disable Metrics/AbcSize
|
|
24
|
+
# rubocop:disable Metrics/MethodLength
|
|
25
|
+
def add_credential_to_authenticator(authenticator, resource, passkey:)
|
|
26
|
+
credential_id = SecureRandom.random_bytes(16)
|
|
27
|
+
encoded_credential_id = Base64.urlsafe_encode64(credential_id)
|
|
28
|
+
key = OpenSSL::PKey.generate_key("ED25519")
|
|
29
|
+
encoded_private_key = Base64.urlsafe_encode64(key.private_to_der)
|
|
30
|
+
|
|
31
|
+
cose_public_key = COSE::Key::OKP.from_pkey(OpenSSL::PKey.read(key.public_to_der))
|
|
32
|
+
cose_public_key.alg = -8
|
|
33
|
+
encoded_cose_public_key = Base64.urlsafe_encode64(cose_public_key.serialize)
|
|
34
|
+
|
|
35
|
+
credential_json = {
|
|
36
|
+
"credentialId" => encoded_credential_id,
|
|
37
|
+
"isResidentCredential" => passkey,
|
|
38
|
+
"rpId" => "localhost",
|
|
39
|
+
"privateKey" => encoded_private_key,
|
|
40
|
+
"signCount" => 0
|
|
41
|
+
}
|
|
42
|
+
credential_json["userHandle"] = resource.webauthn_id if passkey
|
|
43
|
+
|
|
44
|
+
authenticator.add_credential(credential_json)
|
|
45
|
+
|
|
46
|
+
resource.webauthn_credentials.create!(
|
|
47
|
+
name: "My Credential",
|
|
48
|
+
external_id: Base64.urlsafe_encode64(credential_id, padding: false),
|
|
49
|
+
public_key: encoded_cose_public_key,
|
|
50
|
+
sign_count: 0,
|
|
51
|
+
authentication_factor: passkey ? :first_factor : :second_factor
|
|
52
|
+
)
|
|
53
|
+
end
|
|
54
|
+
# rubocop:enable Metrics/MethodLength
|
|
55
|
+
# rubocop:enable Metrics/AbcSize
|
|
14
56
|
end
|
|
15
57
|
end
|
|
16
58
|
end
|
|
@@ -5,7 +5,11 @@ require "rails/generators"
|
|
|
5
5
|
module Devise
|
|
6
6
|
module Webauthn
|
|
7
7
|
class ControllersGenerator < Rails::Generators::Base
|
|
8
|
-
CONTROLLERS = %w[
|
|
8
|
+
CONTROLLERS = %w[
|
|
9
|
+
passkeys
|
|
10
|
+
second_factor_webauthn_credentials
|
|
11
|
+
two_factor_authentications
|
|
12
|
+
].freeze
|
|
9
13
|
|
|
10
14
|
desc "Create inherited Devise::Webauthn controllers in your app/controllers folder."
|
|
11
15
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class <%= @scope_prefix %>SecondFactorWebauthnCredentialsController < Devise::SecondFactorWebauthnCredentialsController
|
|
4
|
+
# GET /resource/second_factor_webauthn_credentials/new
|
|
5
|
+
# def new
|
|
6
|
+
# super
|
|
7
|
+
# end
|
|
8
|
+
|
|
9
|
+
# POST /second_factor_webauthn_credentials/passkeys
|
|
10
|
+
# def create
|
|
11
|
+
# super
|
|
12
|
+
# end
|
|
13
|
+
|
|
14
|
+
# DELETE /resource/second_factor_webauthn_credentials/:id
|
|
15
|
+
# def destroy
|
|
16
|
+
# super
|
|
17
|
+
# end
|
|
18
|
+
|
|
19
|
+
# private
|
|
20
|
+
|
|
21
|
+
# Verifies the security key coming in the params and saves it to the database.
|
|
22
|
+
# def verify_and_save_security_key(security_key_from_params)
|
|
23
|
+
# super
|
|
24
|
+
# end
|
|
25
|
+
|
|
26
|
+
# The default url to be used after creating a second factor key. You can overwrite
|
|
27
|
+
# this method in your own SecondFactorWebauthnCredentialsController.
|
|
28
|
+
# def after_update_path
|
|
29
|
+
# super
|
|
30
|
+
# end
|
|
31
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class <%= @scope_prefix %>TwoFactorAuthenticationsController < Devise::TwoFactorAuthenticationsController
|
|
4
|
+
# GET /resource/two_factor_authentication/new
|
|
5
|
+
# def new
|
|
6
|
+
# super
|
|
7
|
+
# end
|
|
8
|
+
|
|
9
|
+
# POST /resource/two_factor_authentication
|
|
10
|
+
# def create
|
|
11
|
+
# super
|
|
12
|
+
# end
|
|
13
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateWebauthnCredentials < ActiveRecord::Migration[<%= Rails.version.to_f %>]
|
|
4
|
+
def change
|
|
5
|
+
create_table :webauthn_credentials do |t|
|
|
6
|
+
t.string :external_id, null: false
|
|
7
|
+
t.string :name, null: false
|
|
8
|
+
t.text :public_key, null: false
|
|
9
|
+
t.integer :sign_count, limit: 8, null: false
|
|
10
|
+
t.references :<%= user_model_name %>, null: false, foreign_key: true
|
|
11
|
+
t.integer :authentication_factor, limit: 1, null: false
|
|
12
|
+
|
|
13
|
+
t.timestamps
|
|
14
|
+
end
|
|
15
|
+
add_index :webauthn_credentials, :external_id, unique: true
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/generators/devise/webauthn/webauthn_credential_model/webauthn_credential_model_generator.rb
CHANGED
|
@@ -6,22 +6,28 @@ require "rails/generators/active_record"
|
|
|
6
6
|
module Devise
|
|
7
7
|
module Webauthn
|
|
8
8
|
class WebauthnCredentialModelGenerator < Rails::Generators::Base
|
|
9
|
+
include Rails::Generators::Migration
|
|
10
|
+
|
|
9
11
|
hide!
|
|
10
12
|
namespace "devise:webauthn:webauthn_credential_model"
|
|
11
13
|
|
|
14
|
+
source_root File.expand_path("templates", __dir__)
|
|
15
|
+
|
|
12
16
|
desc "Generate a WebauthnCredential model with the required fields for WebAuthn"
|
|
13
17
|
class_option :resource_name, type: :string, default: "user", desc: "The resource name for Devise (default: user)"
|
|
14
18
|
|
|
19
|
+
def self.next_migration_number(dirname)
|
|
20
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
|
21
|
+
end
|
|
22
|
+
|
|
15
23
|
def generate_model
|
|
16
|
-
invoke "active_record:model", [
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"authentication_factor:integer{1}"
|
|
24
|
-
]
|
|
24
|
+
invoke "active_record:model", ["webauthn_credential"], migration: false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# TODO: Remove this in favor of strandard model generator with
|
|
28
|
+
# not null modifier (`!`) once we drop support for Rails < 8.
|
|
29
|
+
def generate_migration
|
|
30
|
+
migration_template "webauthn_credential_migration.rb.erb", "db/migrate/create_webauthn_credentials.rb"
|
|
25
31
|
end
|
|
26
32
|
|
|
27
33
|
def inject_webauthn_credential_content
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cedarcode
|
|
@@ -44,6 +44,7 @@ extensions: []
|
|
|
44
44
|
extra_rdoc_files: []
|
|
45
45
|
files:
|
|
46
46
|
- ".github/FUNDING.yml"
|
|
47
|
+
- ".github/dependabot.yml"
|
|
47
48
|
- ".github/workflows/release.yml"
|
|
48
49
|
- ".github/workflows/ruby.yml"
|
|
49
50
|
- ".gitignore"
|
|
@@ -95,7 +96,10 @@ files:
|
|
|
95
96
|
- lib/generators/devise/webauthn/stimulus/templates/webauthn_credentials_controller.js
|
|
96
97
|
- lib/generators/devise/webauthn/templates/controllers/README
|
|
97
98
|
- lib/generators/devise/webauthn/templates/controllers/passkeys_controller.rb.tt
|
|
99
|
+
- lib/generators/devise/webauthn/templates/controllers/second_factor_webauthn_credentials_controller.rb.tt
|
|
100
|
+
- lib/generators/devise/webauthn/templates/controllers/two_factor_authentications_controller.rb.tt
|
|
98
101
|
- lib/generators/devise/webauthn/views_generator.rb
|
|
102
|
+
- lib/generators/devise/webauthn/webauthn_credential_model/templates/webauthn_credential_migration.rb.erb
|
|
99
103
|
- lib/generators/devise/webauthn/webauthn_credential_model/webauthn_credential_model_generator.rb
|
|
100
104
|
- lib/generators/devise/webauthn/webauthn_id/webauthn_id_generator.rb
|
|
101
105
|
homepage: https://github.com/cedarcode/devise-webauthn
|