passkeys-rails 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +4 -4
  4. data/app/controllers/concerns/passkeys_rails/authentication.rb +29 -0
  5. data/app/controllers/passkeys_rails/application_controller.rb +22 -0
  6. data/app/controllers/passkeys_rails/passkeys_controller.rb +61 -0
  7. data/app/interactors/passkeys_rails/begin_authentication.rb +9 -0
  8. data/app/interactors/passkeys_rails/begin_challenge.rb +35 -0
  9. data/app/interactors/passkeys_rails/begin_registration.rb +23 -0
  10. data/app/interactors/passkeys_rails/finish_authentication.rb +53 -0
  11. data/app/interactors/passkeys_rails/finish_registration.rb +77 -0
  12. data/app/interactors/passkeys_rails/generate_auth_token.rb +27 -0
  13. data/app/interactors/passkeys_rails/refresh_token.rb +17 -0
  14. data/app/interactors/passkeys_rails/validate_auth_token.rb +33 -0
  15. data/app/models/concerns/passkeys_rails/authenticatable.rb +17 -0
  16. data/app/models/passkeys_rails/agent.rb +15 -0
  17. data/app/models/passkeys_rails/application_record.rb +5 -0
  18. data/app/models/passkeys_rails/error.rb +14 -0
  19. data/app/models/passkeys_rails/passkey.rb +8 -0
  20. data/config/initializers/application_controller.rb +12 -0
  21. data/config/routes.rb +1 -1
  22. data/lib/generators/passkeys_rails/USAGE +1 -1
  23. data/lib/generators/passkeys_rails/install_generator.rb +12 -14
  24. data/lib/generators/passkeys_rails/templates/README +1 -1
  25. data/lib/generators/passkeys_rails/templates/passkeys_rails_config.rb +1 -1
  26. data/lib/passkeys-rails.rb +21 -23
  27. data/lib/passkeys_rails/engine.rb +21 -0
  28. data/lib/passkeys_rails/railtie.rb +17 -0
  29. data/lib/passkeys_rails/version.rb +3 -0
  30. metadata +22 -24
  31. data/app/assets/config/passkeys_rails_manifest.js +0 -1
  32. data/app/assets/stylesheets/passkeys_rails/application.css +0 -15
  33. data/app/controllers/passkeys/rails/application_controller.rb +0 -24
  34. data/app/controllers/passkeys/rails/passkeys_controller.rb +0 -63
  35. data/app/models/concerns/passkeys/rails/authenticatable.rb +0 -19
  36. data/app/models/passkeys/rails/agent.rb +0 -17
  37. data/app/models/passkeys/rails/application_record.rb +0 -7
  38. data/app/models/passkeys/rails/error.rb +0 -16
  39. data/app/models/passkeys/rails/passkey.rb +0 -10
  40. data/app/views/layouts/passkeys/rails/application.html.erb +0 -15
  41. data/lib/passkeys/rails/controllers/helpers.rb +0 -33
  42. data/lib/passkeys/rails/engine.rb +0 -44
  43. data/lib/passkeys/rails/interactors/begin_authentication.rb +0 -11
  44. data/lib/passkeys/rails/interactors/begin_challenge.rb +0 -37
  45. data/lib/passkeys/rails/interactors/begin_registration.rb +0 -25
  46. data/lib/passkeys/rails/interactors/finish_authentication.rb +0 -55
  47. data/lib/passkeys/rails/interactors/finish_registration.rb +0 -79
  48. data/lib/passkeys/rails/interactors/generate_auth_token.rb +0 -29
  49. data/lib/passkeys/rails/interactors/refresh_token.rb +0 -19
  50. data/lib/passkeys/rails/interactors/validate_auth_token.rb +0 -35
  51. data/lib/passkeys/rails/railtie.rb +0 -19
  52. data/lib/passkeys/rails/version.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6b2553d498c30365341aba0aad49eafd09c5b49dd5453bbad29c20a026ab39c
4
- data.tar.gz: 795d362e15d977c47b5381a4fe5cc852cdd546a0fa8f81e5a5452343f2b4fa1e
3
+ metadata.gz: 2eb3101d4ecba95639b4cc95adfa6a86939b7bdc3e6db0e3c26ed9e154d9fa97
4
+ data.tar.gz: 86cc744ced315cb5a662743f2cbf44fa20a05f7fbe444103b62a82281b009edd
5
5
  SHA512:
6
- metadata.gz: 15694fd664f6b60343ede055acfefdfef0d8378ffe386420e7cd5d996920fe19a9321ac1148f3e22605b85a8486cbd1f56999167a84be33f9acf950ea0e5e722
7
- data.tar.gz: b6f224af15ee0feb2489c786eefe68293d4854b43b7dcf3a2d17dea4514497cdd5df5f80bd5941972918b4c05864529c62bbe694c09ff58540a87529216bf8f3
6
+ metadata.gz: f2b55ac5a4aea2f969ab32cff126f6cab53f2a0b819a998668d58b794231a4f6ca378247af0e2561fbf0062760ea0724641c36b4915c2bd2a9f24aedf2909a23
7
+ data.tar.gz: 115f5c9c098da302f13d45e6871ae0152a8bd454d4d5281effc29afcc7e1dfacf0b838322bb55ff5f9b17caf2f846917e1596c0f8e4fc8a525bf710e986e7a5f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ### 0.1.4
2
+
3
+ * Changed namespace from Passkeys::Rails to PasskeysRails
4
+
5
+ ### 0.1.3
6
+
7
+ * More restructuring and fixed issue where autoloading failed
8
+ during client app initialization.
9
+
1
10
  ### 0.1.2
2
11
 
3
12
  * Restructured lib directory.
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
- [![Gem Version](https://badge.fury.io/rb/passkeys-rails.svg)](https://badge.fury.io/rb/passkeys-rails)
1
+ [![Gem Version](https://badge.fury.io/rb/passkeys-rails.svg?cachebust=4)](https://badge.fury.io/rb/passkeys-rails)
2
2
  [![Build Status](https://app.travis-ci.com/alliedcode/passkeys-rails.svg?branch=main)](https://travis-ci.org/alliedcode/passkeys-rails)
3
3
  [![codecov](https://codecov.io/gh/alliedcode/passkeys-rails/branch/main/graph/badge.svg?token=UHSNJDUL21)](https://codecov.io/gh/alliedcode/passkeys-rails)
4
4
 
5
- # Passkeys::Rails
5
+ # PasskeysRails
6
6
  Devise is awesome, but we don't need all that UI/UX for PassKeys. This gem is to make it easy to provide a back end that authenticates a mobile front end with PassKeys.
7
7
 
8
8
  ## Usage
9
9
  rails passkeys-rails::install
10
- Passkeys::Rails maintains an Agent model and related Passeys. If you have a user model, add `include Passkeys::Rails::Authenticatable` to your model and include the name of that class (e.g. "User") in the authenticatable_class param when calling the register API.
10
+ PasskeysRails maintains an Agent model and related Passeys. If you have a user model, add `include PasskeysRails::Authenticatable` to your model and include the name of that class (e.g. "User") in the authenticatable_class param when calling the register API.
11
11
 
12
12
  ## Installation
13
13
  Add this line to your application's Gemfile:
@@ -34,7 +34,7 @@ Depending on your application's configuration some manual setup may be required:
34
34
 
35
35
  before_action :authenticate_passkey!, except: [:index]
36
36
 
37
- 2. Optionally include Passkeys::Rails::Authenticatable to the model(s) you are using as
37
+ 2. Optionally include PasskeysRails::Authenticatable to the model(s) you are using as
38
38
  your user model(s). For example, the User model.
39
39
 
40
40
  3. See the reference mobile applications for how to use passkeys-rails for passkey
@@ -0,0 +1,29 @@
1
+ module PasskeysRails
2
+ module Authentication
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ rescue_from PasskeysRails::Error do |e|
7
+ render json: e.to_h, status: :unauthorized
8
+ end
9
+ end
10
+
11
+ def current_agent
12
+ return nil if request.headers['HTTP_X_AUTH'].blank?
13
+
14
+ @current_agent ||= validated_auth_token&.success? && validated_auth_token&.agent
15
+ end
16
+
17
+ def authenticate_passkey!
18
+ return if validated_auth_token.success?
19
+
20
+ raise PasskeysRails::Error.new(:authentication,
21
+ code: :unauthorized,
22
+ message: "You are not authorized to access this resource.")
23
+ end
24
+
25
+ def validated_auth_token
26
+ @validated_auth_token ||= PasskeysRails::ValidateAuthToken.call(auth_token: request.headers['HTTP_X_AUTH'])
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ module PasskeysRails
2
+ class ApplicationController < ActionController::Base
3
+ rescue_from ::Interactor::Failure, with: :handle_interactor_failure
4
+ rescue_from ActionController::ParameterMissing, with: :handle_missing_parameter
5
+
6
+ protected
7
+
8
+ def handle_missing_parameter(error)
9
+ render_error(:authentication, 'missing_parameter', error.message)
10
+ end
11
+
12
+ def handle_interactor_failure(failure)
13
+ render_error(:authentication, failure.context.code, failure.context.message)
14
+ end
15
+
16
+ private
17
+
18
+ def render_error(context, code, message, status: :unprocessable_entity)
19
+ render json: { error: { context:, code:, message: } }, status:
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ module PasskeysRails
2
+ class PasskeysController < ApplicationController
3
+ def challenge
4
+ result = PasskeysRails::BeginChallenge.call!(username: challenge_params[:username])
5
+
6
+ # Store the challenge so we can verify the future register or authentication request
7
+ session[:passkeys_rails] = result.session_data
8
+
9
+ render json: result.response.as_json
10
+ end
11
+
12
+ def register
13
+ result = PasskeysRails::FinishRegistration.call!(credential: attestation_credential_params.to_h,
14
+ authenticatable_class:,
15
+ username: session.dig(:passkeys_rails, :username),
16
+ challenge: session.dig(:passkeys_rails, :challenge))
17
+
18
+ render json: { username: result.username, auth_token: result.auth_token }
19
+ end
20
+
21
+ def authenticate
22
+ result = PasskeysRails::FinishAuthentication.call!(credential: authentication_params.to_h,
23
+ challenge: session.dig(:passkeys_rails, :challenge))
24
+
25
+ render json: { username: result.username, auth_token: result.auth_token }
26
+ end
27
+
28
+ def refresh
29
+ result = PasskeysRails::RefreshToken.call!(token: refresh_params[:auth_token])
30
+ render json: { username: result.username, auth_token: result.auth_token }
31
+ end
32
+
33
+ protected
34
+
35
+ def challenge_params
36
+ params.permit(:username)
37
+ end
38
+
39
+ def attestation_credential_params
40
+ credential = params.require(:credential)
41
+ credential.require(%i[id rawId type response])
42
+ credential.require(:response).require(%i[attestationObject clientDataJSON])
43
+ credential.permit(:id, :rawId, :type, { response: %i[attestationObject clientDataJSON] })
44
+ end
45
+
46
+ def authenticatable_class
47
+ params[:authenticatable_class]
48
+ end
49
+
50
+ def authentication_params
51
+ params.require(%i[id rawId type response])
52
+ params.require(:response).require(%i[authenticatorData clientDataJSON signature userHandle])
53
+ params.permit(:id, :rawId, :type, { response: %i[authenticatorData clientDataJSON signature userHandle] })
54
+ end
55
+
56
+ def refresh_params
57
+ params.require(:auth_token)
58
+ params.permit(:auth_token)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,9 @@
1
+ module PasskeysRails
2
+ class BeginAuthentication
3
+ include Interactor
4
+
5
+ def call
6
+ context.options = WebAuthn::Credential.options_for_get
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ module PasskeysRails
2
+ class BeginChallenge
3
+ include Interactor
4
+
5
+ delegate :username, to: :context
6
+
7
+ def call
8
+ result = generate_challenge!
9
+
10
+ options = result.options
11
+
12
+ context.response = options
13
+ context.session_data = session_data(options)
14
+ rescue Interactor::Failure => e
15
+ context.fail! code: e.context.code, message: e.context.message
16
+ end
17
+
18
+ private
19
+
20
+ def generate_challenge!
21
+ if username.present?
22
+ BeginRegistration.call!(username:)
23
+ else
24
+ BeginAuthentication.call!
25
+ end
26
+ end
27
+
28
+ def session_data(options)
29
+ {
30
+ username:,
31
+ challenge: WebAuthn.standard_encoder.encode(options.challenge)
32
+ }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module PasskeysRails
2
+ class BeginRegistration
3
+ include Interactor
4
+
5
+ delegate :username, to: :context
6
+
7
+ def call
8
+ agent = create_unregistered_agent
9
+
10
+ context.options = WebAuthn::Credential.options_for_create(user: { id: agent.webauthn_identifier, name: agent.username })
11
+ end
12
+
13
+ private
14
+
15
+ def create_unregistered_agent
16
+ agent = Agent.create(username:, webauthn_identifier: WebAuthn.generate_user_id)
17
+
18
+ context.fail!(code: :validation_errors, message: agent.errors.full_messages.to_sentence) unless agent.valid?
19
+
20
+ agent
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,53 @@
1
+ # Finish authentication ceremony
2
+ module PasskeysRails
3
+ class FinishAuthentication
4
+ include Interactor
5
+
6
+ delegate :credential, :challenge, to: :context
7
+
8
+ def call
9
+ verify_credential!
10
+
11
+ context.username = agent.username
12
+ context.auth_token = GenerateAuthToken.call!(agent:).auth_token
13
+ rescue Interactor::Failure => e
14
+ context.fail! code: e.context.code, message: e.context.message
15
+ end
16
+
17
+ private
18
+
19
+ def verify_credential!
20
+ webauthn_credential.verify(
21
+ challenge,
22
+ public_key: passkey.public_key,
23
+ sign_count: passkey.sign_count
24
+ )
25
+
26
+ passkey.update!(sign_count: webauthn_credential.sign_count)
27
+ agent.update!(last_authenticated_at: Time.current)
28
+ rescue WebAuthn::SignCountVerificationError
29
+ # Cryptographic verification of the authenticator data succeeded, but the signature counter was less than or equal
30
+ # to the stored value. This can have several reasons and depending on your risk tolerance you can choose to fail or
31
+ # pass authentication. For more information see https://www.w3.org/TR/webauthn/#sign-counter
32
+ rescue WebAuthn::Error => e
33
+ context.fail!(code: :webauthn_error, message: e.message)
34
+ end
35
+
36
+ def webauthn_credential
37
+ @webauthn_credential ||= WebAuthn::Credential.from_get(credential)
38
+ end
39
+
40
+ def passkey
41
+ @passkey ||= begin
42
+ passkey = Passkey.find_by(identifier: webauthn_credential.id)
43
+ context.fail!(code: :passkey_not_found, message: "Unable to find the specified passkey") if passkey.blank?
44
+
45
+ passkey
46
+ end
47
+ end
48
+
49
+ def agent
50
+ passkey.agent
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,77 @@
1
+ # Finish registration ceremony
2
+ module PasskeysRails
3
+ class FinishRegistration
4
+ include Interactor
5
+
6
+ delegate :credential, :username, :challenge, :authenticatable_class, to: :context
7
+
8
+ def call
9
+ verify_credential!
10
+ store_passkey_and_register_agent!
11
+
12
+ context.username = agent.username
13
+ context.auth_token = GenerateAuthToken.call!(agent:).auth_token
14
+ rescue Interactor::Failure => e
15
+ context.fail! code: e.context.code, message: e.context.message
16
+ end
17
+
18
+ private
19
+
20
+ def verify_credential!
21
+ webauthn_credential.verify(challenge)
22
+ rescue WebAuthn::Error => e
23
+ context.fail!(code: :webauthn_error, message: e.message)
24
+ rescue StandardError => e
25
+ context.fail!(code: :error, message: e.message)
26
+ end
27
+
28
+ def store_passkey_and_register_agent!
29
+ agent.transaction do
30
+ begin
31
+ # Store Credential ID, Credential Public Key and Sign Count for future authentications
32
+ agent.passkeys.create!(
33
+ identifier: webauthn_credential.id,
34
+ public_key: webauthn_credential.public_key,
35
+ sign_count: webauthn_credential.sign_count
36
+ )
37
+
38
+ agent.update! registered_at: Time.current
39
+ rescue StandardError => e
40
+ context.fail! code: :passkey_error, message: e.message
41
+ end
42
+
43
+ create_authenticatable! if authenticatable_class.present?
44
+ end
45
+ end
46
+
47
+ def create_authenticatable!
48
+ klass = begin
49
+ authenticatable_class.constantize
50
+ rescue StandardError
51
+ context.fail!(code: :invalid_authenticatable_class, message: "authenticatable_class (#{authenticatable_class}) is not defined")
52
+ end
53
+
54
+ begin
55
+ authenticatable = klass.create! do |obj|
56
+ obj.registering_with(agent) if obj.respond_to?(:registering_with)
57
+ end
58
+ agent.update!(authenticatable:)
59
+ rescue ActiveRecord::RecordInvalid => e
60
+ context.fail!(code: :record_invalid, message: e.message)
61
+ end
62
+ end
63
+
64
+ def webauthn_credential
65
+ @webauthn_credential ||= WebAuthn::Credential.from_create(credential)
66
+ end
67
+
68
+ def agent
69
+ @agent ||= begin
70
+ agent = Agent.find_by(username:)
71
+ context.fail!(code: :agent_not_found, message: "Agent not found for session value: \"#{username}\"") if agent.blank?
72
+
73
+ agent
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,27 @@
1
+ module PasskeysRails
2
+ class GenerateAuthToken
3
+ include Interactor
4
+
5
+ delegate :agent, to: :context
6
+
7
+ def call
8
+ context.auth_token = generate_auth_token
9
+ end
10
+
11
+ private
12
+
13
+ def generate_auth_token
14
+ JWT.encode(jwt_payload,
15
+ PasskeysRails.auth_token_secret,
16
+ PasskeysRails.auth_token_algorithm)
17
+ end
18
+
19
+ def jwt_payload
20
+ expiration = (Time.current + PasskeysRails.auth_token_expires_in).to_i
21
+
22
+ payload = { agent_id: agent.id }
23
+ payload[:exp] = expiration unless expiration.zero?
24
+ payload
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ # Finish authentication ceremony
2
+ module PasskeysRails
3
+ class RefreshToken
4
+ include Interactor
5
+
6
+ delegate :token, to: :context
7
+
8
+ def call
9
+ agent = ValidateAuthToken.call!(auth_token: token).agent
10
+
11
+ context.username = agent.username
12
+ context.auth_token = GenerateAuthToken.call!(agent:).auth_token
13
+ rescue Interactor::Failure => e
14
+ context.fail! code: e.context.code, message: e.context.message
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ module PasskeysRails
2
+ class ValidateAuthToken
3
+ include Interactor
4
+
5
+ delegate :auth_token, to: :context
6
+
7
+ def call
8
+ context.fail!(code: :missing_token, message: "X-Auth header is required") if auth_token.blank?
9
+
10
+ context.agent = fetch_agent
11
+ end
12
+
13
+ private
14
+
15
+ def fetch_agent
16
+ agent = Agent.find_by(id: payload['agent_id'])
17
+ context.fail!(code: :invalid_token, message: "Invalid token - no agent exists with agent_id") if agent.blank?
18
+
19
+ agent
20
+ end
21
+
22
+ def payload
23
+ JWT.decode(auth_token,
24
+ PasskeysRails.auth_token_secret,
25
+ true,
26
+ { required_claims: %w[exp agent_id], algorithm: PasskeysRails.auth_token_algorithm }).first
27
+ rescue JWT::ExpiredSignature
28
+ context.fail!(code: :expired_token, message: "The token has expired")
29
+ rescue StandardError => e
30
+ context.fail!(code: :token_error, message: e.message)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ require 'active_support/concern'
2
+
3
+ module PasskeysRails
4
+ module Authenticatable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_one :agent, as: :authenticatable
9
+
10
+ delegate :registered?, to: :agent, allow_nil: true
11
+
12
+ def registering_with(_agent)
13
+ # initialize required attributes
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module PasskeysRails
2
+ class Agent < ApplicationRecord
3
+ belongs_to :authenticatable, polymorphic: true, optional: true
4
+ has_many :passkeys
5
+
6
+ scope :registered, -> { where.not registered_at: nil }
7
+ scope :unregistered, -> { where registered_at: nil }
8
+
9
+ validates :username, presence: true, uniqueness: true
10
+
11
+ def registered?
12
+ registered_at.present?
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module PasskeysRails
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ module PasskeysRails
2
+ class Error < StandardError
3
+ attr_reader :hash
4
+
5
+ def initialize(message, hash = {})
6
+ @hash = hash
7
+ super(message)
8
+ end
9
+
10
+ def to_h
11
+ { error: hash.merge(context: message) }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ module PasskeysRails
2
+ class Passkey < ApplicationRecord
3
+ belongs_to :agent
4
+ validates :identifier, presence: true, uniqueness: true
5
+ validates :public_key, presence: true
6
+ validates :sign_count, presence: true
7
+ end
8
+ end
@@ -0,0 +1,12 @@
1
+ # These should be autoloaded, but if these aren't required here, apps using this
2
+ # gem will throw an exception that PasskeysRails::Authentication can't be found
3
+ require_relative '../../app/controllers/concerns/passkeys_rails/authentication'
4
+ require_relative '../../app/models/passkeys_rails/error'
5
+
6
+ class ActionController::Base
7
+ include PasskeysRails::Authentication
8
+ end
9
+
10
+ class ActionController::API
11
+ include PasskeysRails::Authentication
12
+ end
data/config/routes.rb CHANGED
@@ -1,4 +1,4 @@
1
- Passkeys::Rails::Engine.routes.draw do
1
+ PasskeysRails::Engine.routes.draw do
2
2
  post 'passkeys/challenge'
3
3
  post 'passkeys/register'
4
4
  post 'passkeys/authenticate'
@@ -1,5 +1,5 @@
1
1
  Description:
2
- Creates a Passkeys::Rails config file, updates the routes and adds migrations.
2
+ Creates a PasskeysRails config file, updates the routes and adds migrations.
3
3
 
4
4
  Example:
5
5
  bin/rails generate passkeys-rails:install
@@ -1,22 +1,20 @@
1
1
  require 'rails/generators'
2
2
 
3
- module Passkeys
4
- module Rails
5
- module Generators
6
- class InstallGenerator < ::Rails::Generators::Base
7
- source_root File.expand_path("templates", __dir__)
3
+ module PasskeysRails
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
8
7
 
9
- def copy_config
10
- template 'passkeys_rails_config.rb', "config/initializers/passkeys_rails.rb"
11
- end
8
+ def copy_config
9
+ template 'passkeys_rails_config.rb', "config/initializers/passkeys_rails.rb"
10
+ end
12
11
 
13
- def add_routes
14
- route 'mount Passkeys::Rails::Engine => "/passkeys_rails"'
15
- end
12
+ def add_routes
13
+ route 'mount PasskeysRails::Engine => "/passkeys_rails"'
14
+ end
16
15
 
17
- def show_readme
18
- readme "README" if behavior == :invoke
19
- end
16
+ def show_readme
17
+ readme "README" if behavior == :invoke
20
18
  end
21
19
  end
22
20
  end
@@ -8,7 +8,7 @@ Depending on your application's configuration some manual setup may be required:
8
8
 
9
9
  before_action :authenticate_passkey!, except: [:index]
10
10
 
11
- 2. Optionally include Passkeys::Rails::Authenticatable to the model(s) you are using as
11
+ 2. Optionally include PasskeysRails::Authenticatable to the model(s) you are using as
12
12
  your user model(s). For example, the User model.
13
13
 
14
14
  3. See the reference mobile applications for how to use passkeys-rails for passkey
@@ -1,6 +1,6 @@
1
1
  require 'passkeys-rails'
2
2
 
3
- Passkeys::Rails.config do |c|
3
+ PasskeysRails.config do |c|
4
4
  # Secret used to encode the auth token.
5
5
  # Changing this value will invalidate all tokens that have been fetched
6
6
  # through the API.
@@ -1,36 +1,34 @@
1
1
  # rubocop:disable Naming/FileName
2
- require 'passkeys/rails/engine'
3
- require 'passkeys/rails/version'
2
+ require 'passkeys_rails/engine'
3
+ require 'passkeys_rails/version'
4
4
  require_relative "generators/passkeys_rails/install_generator"
5
5
 
6
- module Passkeys
7
- module Rails
8
- # Secret used to encode the auth token.
9
- # Rails.application.secret_key_base is used if none is defined here.
10
- # Changing this value will invalidate all tokens that have been fetched
11
- # through the API.
12
- mattr_accessor(:auth_token_secret)
6
+ module PasskeysRails
7
+ # Secret used to encode the auth token.
8
+ # Rails.application.secret_key_base is used if none is defined here.
9
+ # Changing this value will invalidate all tokens that have been fetched
10
+ # through the API.
11
+ mattr_accessor(:auth_token_secret)
13
12
 
14
- # Algorithm used to generate the auth token.
15
- # Changing this value will invalidate all tokens that have been fetched
16
- # through the API.
17
- mattr_accessor :auth_token_algorithm, default: "HS256"
13
+ # Algorithm used to generate the auth token.
14
+ # Changing this value will invalidate all tokens that have been fetched
15
+ # through the API.
16
+ mattr_accessor :auth_token_algorithm, default: "HS256"
18
17
 
19
- # How long the auth token is valid before requiring a refresh or new login.
20
- # Set it to 0 for no expiration (not recommended in production).
21
- mattr_accessor :auth_token_expires_in, default: 30.days
18
+ # How long the auth token is valid before requiring a refresh or new login.
19
+ # Set it to 0 for no expiration (not recommended in production).
20
+ mattr_accessor :auth_token_expires_in, default: 30.days
22
21
 
23
- class << self
24
- def config
25
- yield self
26
- end
22
+ class << self
23
+ def config
24
+ yield self
27
25
  end
28
-
29
- require 'passkeys/rails/railtie' if defined?(Rails)
30
26
  end
27
+
28
+ require 'passkeys_rails/railtie' if defined?(Rails)
31
29
  end
32
30
 
33
31
  ActiveSupport.on_load(:before_initialize) do
34
- Passkeys::Rails.auth_token_secret ||= Rails.application.secret_key_base
32
+ PasskeysRails.auth_token_secret ||= Rails.application.secret_key_base
35
33
  end
36
34
  # rubocop:enable Naming/FileName