passkeys-rails 0.1.5 → 0.1.6

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: c1967aeb595e4864973402bf8108fe5a56b668678b8ed56aafbc403b164c628d
4
- data.tar.gz: c96c2cd39bedbc138c1cd35248432d9cf7626c5a96007b91981741eb6f56e478
3
+ metadata.gz: c1c218e160d157a8ddcf931fae3a053fb6e130130b61a8e03f5a9a2bcade07b1
4
+ data.tar.gz: 42fb39898dd79867bd8d18fb95b39ac335a47ed5a06d3ccb13b5f3fc2b64b6af
5
5
  SHA512:
6
- metadata.gz: 3eb9182122196e3c94b5ebb78b0984785c39fb194b6d7f5f95432eb63e53482be0190fe24bc2af914a38377ee1a82df80932b11c16f918d155fdbaa731b5a052
7
- data.tar.gz: e16475967c805796248fb3188667456e31fd833f841b98d16c28a6b5964e59170d349a018580a5e1ab312f18f7a9f7f16693b612d70d97f6ce91a5a77a9e5db4
6
+ metadata.gz: 85c226aabf90e17b56744947b37eab49f98c4cbacc42a4963316ea60a68fa6c49b40ea81297d2786a16151361fa6e0f637a5af18d147db12894f5288ef260558
7
+ data.tar.gz: 9a26aa0b7c5e907b954f2564244ab222205775da8087c0c9b17cde3e00706aace1b21b4c3c57d728b91472ed035eeb3f4c87d2ecc4ccecb1e41c5f767d548ccc
data/README.md CHANGED
@@ -3,11 +3,39 @@
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
5
  # PasskeysRails
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.
6
+ Devise is awesome, but we don't need all that UI/UX for PassKeys. This gem is to make
7
+ it easy to provide a back end that authenticates a mobile front end with PassKeys.
7
8
 
8
9
  ## Usage
9
10
  rails passkeys-rails::install
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
+ PasskeysRails maintains an Agent model and related Passeys. If you have a user model,
12
+ add `include PasskeysRails::Authenticatable` to your model and include the name of that
13
+ class (e.g. "User") in the authenticatable_class param when calling the register API.
14
+
15
+ ### Optionally providing a "user" model during registration
16
+ PasskeysRails does not require that you supply your own model, but it's often useful to do so. For example,
17
+ if you have a User model that you would like to have created at registration, you can supply the model name
18
+ in the finishRegistration API call.
19
+
20
+ PasskeysRails supports multiple "user" models. Whatever model name you supply in the finishRegiration call will
21
+ be created and provided an opportunity to do any required initialization at that time.
22
+
23
+ There are two PasskeysRails configuration options related to this.
24
+
25
+ default_class and class_whitelist
26
+
27
+ #### default_class
28
+
29
+ Configure default_class in passkeys_rails.rb. Its value will be used during registration if none
30
+ is provided in the API call. It is "User" by default. Since it's just a default, it can be overridden
31
+ in the API call for any other model. If no model is to be used, change it to nil.
32
+
33
+ #### class_whitelist
34
+
35
+ Configure class_whitelist in passkeys_rails.rb. It is nil by default. When nil, no whitelist will be applied.
36
+ If it is non-nil, it should be an array of class names that are allowed during registration. Supply an empty
37
+ array to prevent PasskeysRails from attempting to create anything other than its own PasskeysRails::Agent during
38
+ registration.
11
39
 
12
40
  ## Installation
13
41
  Add this line to your application's Gemfile:
@@ -40,25 +40,42 @@ module PasskeysRails
40
40
  context.fail! code: :passkey_error, message: e.message
41
41
  end
42
42
 
43
- create_authenticatable! if authenticatable_class.present?
43
+ create_authenticatable! if aux_class_name.present?
44
44
  end
45
45
  end
46
46
 
47
- def create_authenticatable!
48
- klass = begin
49
- authenticatable_class.constantize
47
+ def aux_class_name
48
+ @aux_class_name ||= authenticatable_class || PasskeysRails.default_class
49
+ end
50
+
51
+ def aux_class
52
+ whitelist = PasskeysRails.class_whitelist
53
+
54
+ @aux_class ||= begin
55
+ case whitelist
56
+ when Array
57
+ unless whitelist.include?(aux_class_name)
58
+ context.fail!(code: :invalid_authenticatable_class, message: "authenticatable_class (#{aux_class_name}) is not in the whitelist")
59
+ end
60
+ when present?
61
+ context.fail!(code: :invalid_class_whitelist,
62
+ message: "class_whitelist is invalid. It should be nil or an array of zero or more class names.")
63
+ end
64
+
65
+ aux_class_name.constantize
50
66
  rescue StandardError
51
- context.fail!(code: :invalid_authenticatable_class, message: "authenticatable_class (#{authenticatable_class}) is not defined")
67
+ context.fail!(code: :invalid_authenticatable_class, message: "authenticatable_class (#{aux_class_name}) is not defined")
52
68
  end
69
+ end
53
70
 
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)
71
+ def create_authenticatable!
72
+ authenticatable = aux_class.create! do |obj|
73
+ obj.registering_with(agent) if obj.respond_to?(:registering_with)
61
74
  end
75
+
76
+ agent.update!(authenticatable:)
77
+ rescue ActiveRecord::RecordInvalid => e
78
+ context.fail!(code: :record_invalid, message: e.message)
62
79
  end
63
80
 
64
81
  def webauthn_credential
@@ -21,4 +21,28 @@ PasskeysRails.config do |c|
21
21
  # Default is 30 days
22
22
  #
23
23
  # c.auth_token_expires_in = 30.days
24
+
25
+ # Model to use when creating or authenticating a passkey.
26
+ # This can be overridden when calling the API, but if no
27
+ # value is supplied when calling the API, this value is used.
28
+ #
29
+ # If nil, there is no default, and if none is supplied when
30
+ # calling the API, no resource is created other than
31
+ # a PaskeysRails::Agent that is used to track the passkey.
32
+ #
33
+ # This library doesn't assume that there will only be one
34
+ # model, but it is a common use case, so setting the
35
+ # default_class simplifies the use of the API in that case.
36
+ #
37
+ # c.default_class = "User"
38
+
39
+ # By providing a class_whitelist, the API will require that
40
+ # any supplied class is in the whitelist. If it is not, the
41
+ # auth API will return an error. This prevents a caller from
42
+ # attempting to create an unintended records on registration.
43
+ # If nil, any model will be allowed.
44
+ # This should be an array of symbols or strings,
45
+ # for example: %w[User AdminUser]
46
+ #
47
+ # c.class_whitelist = nil
24
48
  end
@@ -19,6 +19,28 @@ module PasskeysRails
19
19
  # Set it to 0 for no expiration (not recommended in production).
20
20
  mattr_accessor :auth_token_expires_in, default: 30.days
21
21
 
22
+ # Model to use when creating or authenticating a passkey.
23
+ # This can be overridden when calling the API, but if no
24
+ # value is supplied when calling the API, this value is used.
25
+ # If nil, there is no default, and if none is supplied when
26
+ # calling the API, no resource is created other than
27
+ # a PaskeysRails::Agent that is used to track the passkey.
28
+ #
29
+ # This library doesn't assume that there will only be one
30
+ # model, but it is a common use case, so setting the
31
+ # default_class simplifies the use of the API in that case.
32
+ mattr_accessor :default_class, default: "User"
33
+
34
+ # By providing a class_whitelist, the API will require that
35
+ # any supplied class is in the whitelist. If it is not, the
36
+ # auth API will return an error. This prevents a caller from
37
+ # attempting to create an unintended record on registration.
38
+ # If nil, any model will be allowed.
39
+ # If [], no model will be allowed.
40
+ # This should be an array of symbols or strings,
41
+ # for example: %w[User AdminUser]
42
+ mattr_accessor :class_whitelist, default: nil
43
+
22
44
  class << self
23
45
  def config
24
46
  yield self
@@ -1,3 +1,3 @@
1
1
  module PasskeysRails
2
- VERSION = "0.1.5".freeze
2
+ VERSION = "0.1.6".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passkeys-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Troy Anderson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-24 00:00:00.000000000 Z
11
+ date: 2023-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails