rodauth-oauth 0.8.0 → 0.9.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -3
  3. data/doc/release_notes/0_9_0.md +56 -0
  4. data/doc/release_notes/0_9_1.md +9 -0
  5. data/doc/release_notes/0_9_2.md +10 -0
  6. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +22 -1
  7. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb +8 -3
  8. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb +8 -2
  9. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb +1 -0
  10. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +1 -0
  11. data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb +1 -0
  12. data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +13 -1
  13. data/lib/rodauth/features/oauth.rb +2 -2
  14. data/lib/rodauth/features/oauth_application_management.rb +23 -7
  15. data/lib/rodauth/features/oauth_assertion_base.rb +1 -1
  16. data/lib/rodauth/features/oauth_authorization_code_grant.rb +4 -1
  17. data/lib/rodauth/features/oauth_base.rb +57 -14
  18. data/lib/rodauth/features/oauth_client_credentials_grant.rb +33 -0
  19. data/lib/rodauth/features/oauth_device_grant.rb +4 -5
  20. data/lib/rodauth/features/oauth_dynamic_client_registration.rb +252 -0
  21. data/lib/rodauth/features/oauth_jwt.rb +251 -49
  22. data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +1 -0
  23. data/lib/rodauth/features/oauth_management_base.rb +72 -0
  24. data/lib/rodauth/features/oauth_pkce.rb +1 -1
  25. data/lib/rodauth/features/oauth_token_management.rb +8 -6
  26. data/lib/rodauth/features/oidc.rb +37 -7
  27. data/lib/rodauth/features/oidc_dynamic_client_registration.rb +147 -0
  28. data/lib/rodauth/oauth/jwe_extensions.rb +64 -0
  29. data/lib/rodauth/oauth/ttl_store.rb +9 -3
  30. data/lib/rodauth/oauth/version.rb +1 -1
  31. data/locales/en.yml +6 -1
  32. data/templates/authorize.str +50 -1
  33. data/templates/jwks_field.str +4 -0
  34. data/templates/jwt_public_key_field.str +1 -1
  35. data/templates/new_oauth_application.str +1 -1
  36. data/templates/oauth_application.str +1 -1
  37. data/templates/oauth_application_oauth_tokens.str +1 -0
  38. data/templates/oauth_applications.str +1 -0
  39. data/templates/oauth_tokens.str +1 -0
  40. data/templates/scope_field.str +3 -2
  41. metadata +14 -3
  42. data/templates/jws_jwk_field.str +0 -4
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rodauth
4
+ Feature.define(:oidc_dynamic_client_registration, :OidcDynamicClientRegistration) do
5
+ depends :oauth_dynamic_client_registration, :oidc
6
+
7
+ auth_value_method :oauth_applications_application_type_column, :application_type
8
+
9
+ private
10
+
11
+ def registration_metadata
12
+ openid_configuration_body
13
+ end
14
+
15
+ def validate_client_registration_params
16
+ super
17
+
18
+ if (value = @oauth_application_params[oauth_applications_application_type_column])
19
+ case value
20
+ when "native"
21
+ request.params["redirect_uris"].each do |uri|
22
+ uri = URI(uri)
23
+ # Native Clients MUST only register redirect_uris using custom URI schemes or
24
+ # URLs using the http: scheme with localhost as the hostname.
25
+ case uri.scheme
26
+ when "http"
27
+ register_throw_json_response_error("invalid_redirect_uri", register_invalid_uri_message(uri)) unless uri.host == "localhost"
28
+ when "https"
29
+ register_throw_json_response_error("invalid_redirect_uri", register_invalid_uri_message(uri))
30
+ end
31
+ end
32
+ when "web"
33
+ # Web Clients using the OAuth Implicit Grant Type MUST only register URLs using the https scheme as redirect_uris;
34
+ # they MUST NOT use localhost as the hostname.
35
+ if request.params["grant_types"].include?("implicit")
36
+ request.params["redirect_uris"].each do |uri|
37
+ uri = URI(uri)
38
+ unless uri.scheme == "https" && uri.host != "localhost"
39
+ register_throw_json_response_error("invalid_redirect_uri", register_invalid_uri_message(uri))
40
+ end
41
+ end
42
+ end
43
+ else
44
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_application_type_message(type))
45
+ end
46
+ elsif (value = @oauth_application_params[oauth_applications_subject_type_column])
47
+ unless %w[pairwise public].include?(value)
48
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("subject_type"))
49
+ end
50
+ elsif (value = @oauth_application_params[oauth_applications_id_token_signed_response_alg_column])
51
+ if value == "none"
52
+ # The value none MUST NOT be used as the ID Token alg value unless the Client uses only Response Types
53
+ # that return no ID Token from the Authorization Endpoint
54
+ response_types = @oauth_application_params[oauth_applications_response_types_column]
55
+ if response_types && response_types.include?("id_token")
56
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("id_token_signed_response_alg"))
57
+ end
58
+ elsif !oauth_jwt_algorithms_supported.include?(value)
59
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("id_token_signed_response_alg"))
60
+ end
61
+ elsif (value = @oauth_application_params[oauth_applications_id_token_encrypted_response_alg_column])
62
+ unless oauth_jwt_jwe_algorithms_supported.include?(value)
63
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("id_token_encrypted_response_alg"))
64
+ end
65
+ elsif (value = @oauth_application_params[oauth_applications_id_token_encrypted_response_enc_column])
66
+ unless oauth_jwt_jwe_encryption_methods_supported.include?(value)
67
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("id_token_encrypted_response_enc"))
68
+ end
69
+ elsif (value = @oauth_application_params[oauth_applications_userinfo_signed_response_alg_column])
70
+ unless oauth_jwt_algorithms_supported.include?(value)
71
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("userinfo_signed_response_alg"))
72
+ end
73
+ elsif (value = @oauth_application_params[oauth_applications_userinfo_encrypted_response_alg_column])
74
+ unless oauth_jwt_jwe_algorithms_supported.include?(value)
75
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("userinfo_encrypted_response_alg"))
76
+ end
77
+ elsif (value = @oauth_application_params[oauth_applications_userinfo_encrypted_response_enc_column])
78
+ unless oauth_jwt_jwe_encryption_methods_supported.include?(value)
79
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("userinfo_encrypted_response_enc"))
80
+ end
81
+ elsif (value = @oauth_application_params[oauth_applications_request_object_signing_alg_column])
82
+ unless oauth_jwt_algorithms_supported.include?(value)
83
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("request_object_signing_alg"))
84
+ end
85
+ elsif (value = @oauth_application_params[oauth_applications_request_object_encryption_alg_column])
86
+ unless oauth_jwt_jwe_algorithms_supported.include?(value)
87
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("request_object_encryption_alg"))
88
+ end
89
+ elsif (value = @oauth_application_params[oauth_applications_request_object_encryption_enc_column])
90
+ unless oauth_jwt_jwe_encryption_methods_supported.include?(value)
91
+ register_throw_json_response_error("invalid_client_metadata", register_invalid_param_message("request_object_encryption_enc"))
92
+ end
93
+ end
94
+ end
95
+
96
+ def validate_client_registration_response_type(response_type, grant_types)
97
+ case response_type
98
+ when "id_token"
99
+ unless grant_types.include?("implicit")
100
+ register_throw_json_response_error("invalid_client_metadata",
101
+ register_invalid_response_type_for_grant_type_message(response_type, "implicit"))
102
+ end
103
+ else
104
+ super
105
+ end
106
+ end
107
+
108
+ def do_register(return_params = request.params.dup)
109
+ # set defaults
110
+
111
+ create_params = @oauth_application_params
112
+
113
+ create_params[oauth_applications_application_type_column] ||= begin
114
+ return_params["application_type"] = "web"
115
+ "web"
116
+ end
117
+ create_params[oauth_applications_id_token_signed_response_alg_column] ||= begin
118
+ return_params["id_token_signed_response_alg"] = oauth_jwt_algorithm
119
+ oauth_jwt_algorithm
120
+ end
121
+ if create_params.key?(oauth_applications_id_token_encrypted_response_alg_column)
122
+ create_params[oauth_applications_id_token_encrypted_response_enc_column] ||= begin
123
+ return_params["id_token_encrypted_response_enc"] = "A128CBC-HS256"
124
+ "A128CBC-HS256"
125
+ end
126
+ end
127
+ if create_params.key?(oauth_applications_userinfo_encrypted_response_alg_column)
128
+ create_params[oauth_applications_userinfo_encrypted_response_enc_column] ||= begin
129
+ return_params["userinfo_encrypted_response_enc"] = "A128CBC-HS256"
130
+ "A128CBC-HS256"
131
+ end
132
+ end
133
+ if create_params.key?(oauth_applications_request_object_encryption_alg_column)
134
+ create_params[oauth_applications_request_object_encryption_enc_column] ||= begin
135
+ return_params["request_object_encryption_enc"] = "A128CBC-HS256"
136
+ "A128CBC-HS256"
137
+ end
138
+ end
139
+
140
+ super(return_params)
141
+ end
142
+
143
+ def register_invalid_application_type_message(application_type)
144
+ "The application type '#{application_type}' is not allowed."
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWE
4
+ #
5
+ # this is a monkey-patch!
6
+ # it's necessary, as the original jwe does not support jwks.
7
+ # if this works long term, it may be merged upstreamm.
8
+ #
9
+ def self.__rodauth_oauth_decrypt_from_jwks(payload, jwks, alg: "RSA-OAEP", enc: "A128GCM")
10
+ header, enc_key, iv, ciphertext, tag = Serialization::Compact.decode(payload)
11
+ header = JSON.parse(header)
12
+
13
+ key = find_key_by_kid(jwks, header["kid"], alg, enc)
14
+
15
+ check_params(header, key)
16
+
17
+ cek = Alg.decrypt_cek(header["alg"], key, enc_key)
18
+ cipher = Enc.for(header["enc"], cek, iv, tag)
19
+
20
+ plaintext = cipher.decrypt(ciphertext, payload.split(".").first)
21
+
22
+ apply_zip(header, plaintext, :decompress)
23
+ end
24
+
25
+ def self.__rodauth_oauth_encrypt_from_jwks(payload, jwks, alg: "RSA-OAEP", enc: "A128GCM", **more_headers)
26
+ header = generate_header(alg, enc, more_headers)
27
+
28
+ key = find_key_by_alg_enc(jwks, alg, enc)
29
+
30
+ check_params(header, key)
31
+ payload = apply_zip(header, payload, :compress)
32
+
33
+ cipher = Enc.for(enc)
34
+ cipher.cek = key if alg == "dir"
35
+
36
+ json_hdr = header.to_json
37
+ ciphertext = cipher.encrypt(payload, Base64.jwe_encode(json_hdr))
38
+
39
+ generate_serialization(json_hdr, Alg.encrypt_cek(alg, key, cipher.cek), ciphertext, cipher)
40
+ end
41
+
42
+ def self.find_key_by_kid(jwks, kid, alg, enc)
43
+ raise DecodeError, "No key id (kid) found from token headers" unless kid
44
+
45
+ jwk = jwks.find { |key, _| (key[:kid] || key["kid"]) == kid }
46
+
47
+ raise DecodeError, "Could not find public key for kid #{kid}" unless jwk
48
+ raise DecodeError, "Expected a different encryption algorithm" unless alg == (jwk[:alg] || jwk["alg"])
49
+ raise DecodeError, "Expected a different encryption method" unless enc == (jwk[:enc] || jwk["enc"])
50
+
51
+ ::JWT::JWK.import(jwk).keypair
52
+ end
53
+
54
+ def self.find_key_by_alg_enc(jwks, alg, enc)
55
+ jwk = jwks.find do |key, _|
56
+ (key[:alg] || key["alg"]) == alg &&
57
+ (key[:enc] || key["enc"]) == enc
58
+ end
59
+
60
+ raise DecodeError, "No key found" unless jwk
61
+
62
+ ::JWT::JWK.import(jwk).keypair
63
+ end
64
+ end
@@ -24,12 +24,18 @@ class Rodauth::OAuth::TtlStore
24
24
  @store_mutex.synchronize do
25
25
  # short circuit
26
26
  return @store[key][:payload] if @store[key] && @store[key][:ttl] < now
27
+ end
27
28
 
28
- payload, ttl = block.call
29
- @store[key] = { payload: payload, ttl: (ttl || (now + DEFAULT_TTL)) }
29
+ payload, ttl = block.call
30
+
31
+ @store_mutex.synchronize do
32
+ # given that the block call triggers network, and two requests for the same key be processed
33
+ # at the same time, this ensures the first one wins.
34
+ return @store[key][:payload] if @store[key] && @store[key][:ttl] < now
30
35
 
31
- @store[key][:payload]
36
+ @store[key] = { payload: payload, ttl: (ttl || (now + DEFAULT_TTL)) }
32
37
  end
38
+ @store[key][:payload]
33
39
  end
34
40
 
35
41
  def uncache(key)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rodauth
4
4
  module OAuth
5
- VERSION = "0.8.0"
5
+ VERSION = "0.9.2"
6
6
  end
7
7
  end
data/locales/en.yml CHANGED
@@ -15,10 +15,15 @@ en:
15
15
  oauth_tokens_page_title: "My Oauth Tokens"
16
16
  device_verification_page_title: "Device Verification"
17
17
  device_search_page_title: "Device Search"
18
+ oauth_management_pagination_previous_button: "Previous"
19
+ oauth_management_pagination_next_button: "Next"
18
20
  oauth_applications_name_label: "Name"
19
21
  oauth_applications_description_label: "Description"
20
- oauth_applications_scopes_label: "Scopes"
22
+ oauth_applications_scopes_label: "Default scopes"
23
+ oauth_applications_contacts_label: "Contacts"
21
24
  oauth_applications_homepage_url_label: "Homepage URL"
25
+ oauth_applications_tos_uri_label: "Terms of Service URL"
26
+ oauth_applications_policy_uri_label: "Policy URL"
22
27
  oauth_applications_redirect_uri_label: "Redirect URL"
23
28
  oauth_applications_client_secret_label: "Client Secret"
24
29
  oauth_applications_client_id_label: "Client ID"
@@ -1,6 +1,55 @@
1
1
  <form method="post" action="#{rodauth.authorize_path}" class="form-horizontal" role="form" id="authorize-form">
2
2
  #{csrf_tag(rodauth.authorize_path) if respond_to?(:csrf_tag)}
3
- <p class="lead">The application #{rodauth.oauth_application[rodauth.oauth_applications_name_column]} would like to access your data.</p>
3
+ #{
4
+ if rodauth.oauth_application[rodauth.oauth_applications_logo_uri_column]
5
+ <<-HTML
6
+ <img src="#{h(rodauth.oauth_application[rodauth.oauth_applications_logo_uri_column])}" />
7
+ HTML
8
+ end
9
+ }
10
+ <p class="lead">
11
+ The application
12
+ <a target="_blank" href="#{h(rodauth.oauth_application[rodauth.oauth_applications_homepage_url_column])}">
13
+ #{h(rodauth.oauth_application[rodauth.oauth_applications_name_column])}
14
+ </a> would like to access your data.
15
+ </p>
16
+ <div class="list-group">
17
+ #{
18
+ if rodauth.oauth_application[rodauth.oauth_applications_tos_uri_column]
19
+ <<-HTML
20
+ <a class="list-group-item" target="_blank" href="#{h(rodauth.oauth_application[rodauth.oauth_applications_tos_uri_column])}">
21
+ #{rodauth.oauth_applications_tos_uri_label}
22
+ </a>
23
+ HTML
24
+ end
25
+ }
26
+ #{
27
+ if rodauth.oauth_application[rodauth.oauth_applications_policy_uri_column]
28
+ <<-HTML
29
+ <a class="list-group-item" target="_blank" href="#{h(rodauth.oauth_application[rodauth.oauth_applications_policy_uri_column])}">
30
+ #{rodauth.oauth_applications_policy_uri_label}
31
+ </a>
32
+ HTML
33
+ end
34
+ }
35
+ </div>
36
+
37
+ #{
38
+ if rodauth.oauth_application[rodauth.oauth_applications_contacts_column]
39
+ data = <<-HTML
40
+ <div class="list-group">
41
+ <h3 class="display-6">#{rodauth.oauth_applications_contacts_label}</h3>
42
+ HTML
43
+ rodauth.oauth_application[rodauth.oauth_applications_contacts_column].split(/ +/).each do |contact|
44
+ data << <<-HTML
45
+ <div class="list-group-item">
46
+ #{h(contact)}
47
+ </div>
48
+ HTML
49
+ end
50
+ data << "</div>"
51
+ end
52
+ }
4
53
 
5
54
  <div class="form-group">
6
55
  <h1 class="display-6">#{rodauth.oauth_tokens_scopes_label}</h1>
@@ -0,0 +1,4 @@
1
+ <div class="form-group">
2
+ <label for="name">#{rodauth.oauth_applications_jwks_label}#{rodauth.input_field_label_suffix}</label>
3
+ <textarea id="jwks" class="form-control" name="#{rodauth.oauth_application_jwks_param}" rows="3"></textarea>
4
+ </div>
@@ -1,4 +1,4 @@
1
1
  <div class="form-group">
2
2
  <label for="name">#{rodauth.oauth_applications_jwt_public_key_label}#{rodauth.input_field_label_suffix}</label>
3
- #{rodauth.input_field_string(rodauth.oauth_application_jwt_public_key_param, "jwt_public_key", :type=>"text")}
3
+ #{rodauth.input_field_string(rodauth.oauth_application_jwt_public_key_param, "jwt_public_key", :type=>"text", :required=>false)}
4
4
  </div>
@@ -11,7 +11,7 @@
11
11
  if rodauth.features.include?(:oauth_jwt)
12
12
  <<-HTML
13
13
  #{rodauth.render('jwt_public_key_field')}
14
- #{rodauth.render('jws_jwk_field')}
14
+ #{rodauth.render('jwks_field')}
15
15
  HTML
16
16
  end
17
17
  }
@@ -3,7 +3,7 @@
3
3
  #{
4
4
  params = [*rodauth.oauth_application_required_params, "client_id", "client_secret"]
5
5
  if rodauth.features.include?(:oauth_jwt)
6
- params += %w[jws_jwk jwt_public_key]
6
+ params += %w[jwks jwt_public_key]
7
7
  end
8
8
  params.map do |param|
9
9
  "<dt class=\"#{param}\">#{rodauth.send(:"oauth_applications_#{param}_label")}: </dt>" +
@@ -45,6 +45,7 @@
45
45
  }
46
46
  </tbody>
47
47
  </table>
48
+ #{rodauth.oauth_management_pagination_links(@oauth_tokens)}
48
49
  HTML
49
50
  end
50
51
  }
@@ -11,4 +11,5 @@
11
11
  "</ul>"
12
12
  end
13
13
  }
14
+ #{rodauth.oauth_management_pagination_links(@oauth_applications)}
14
15
  </div>
@@ -43,6 +43,7 @@
43
43
  }
44
44
  </tbody>
45
45
  </table>
46
+ #{rodauth.oauth_management_pagination_links(@oauth_tokens)}
46
47
  HTML
47
48
  end
48
49
  }
@@ -1,8 +1,9 @@
1
1
  <fieldset class="form-group">
2
+ <legend>#{rodauth.oauth_applications_scopes_label}</legend>
2
3
  #{
3
4
  rodauth.oauth_application_scopes.map do |scope|
4
- "<div class=\"form-check checkbox\">" +
5
- "<input id=\"#{scope}\" type=\"checkbox\" name=\"#{rodauth.oauth_application_scopes_param}[]\" value=\"#{scope}\">" +
5
+ "<div class=\"form-group form-check\">" +
6
+ "<input id=\"#{scope}\" type=\"checkbox\" class=\"form-check-input\" name=\"#{rodauth.oauth_application_scopes_param}[]\" value=\"#{scope}\">" +
6
7
  "<label for=\"#{scope}\">#{scope}</label>" +
7
8
  "</div>"
8
9
  end.join
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth-oauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tiago Cardoso
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-12 00:00:00.000000000 Z
11
+ date: 2022-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rodauth
@@ -56,6 +56,9 @@ extra_rdoc_files:
56
56
  - doc/release_notes/0_7_3.md
57
57
  - doc/release_notes/0_7_4.md
58
58
  - doc/release_notes/0_8_0.md
59
+ - doc/release_notes/0_9_0.md
60
+ - doc/release_notes/0_9_1.md
61
+ - doc/release_notes/0_9_2.md
59
62
  files:
60
63
  - CHANGELOG.md
61
64
  - LICENSE.txt
@@ -83,6 +86,9 @@ files:
83
86
  - doc/release_notes/0_7_3.md
84
87
  - doc/release_notes/0_7_4.md
85
88
  - doc/release_notes/0_8_0.md
89
+ - doc/release_notes/0_9_0.md
90
+ - doc/release_notes/0_9_1.md
91
+ - doc/release_notes/0_9_2.md
86
92
  - lib/generators/rodauth/oauth/install_generator.rb
87
93
  - lib/generators/rodauth/oauth/templates/app/models/oauth_application.rb
88
94
  - lib/generators/rodauth/oauth/templates/app/models/oauth_grant.rb
@@ -103,11 +109,14 @@ files:
103
109
  - lib/rodauth/features/oauth_authorization_code_grant.rb
104
110
  - lib/rodauth/features/oauth_authorization_server.rb
105
111
  - lib/rodauth/features/oauth_base.rb
112
+ - lib/rodauth/features/oauth_client_credentials_grant.rb
106
113
  - lib/rodauth/features/oauth_device_grant.rb
114
+ - lib/rodauth/features/oauth_dynamic_client_registration.rb
107
115
  - lib/rodauth/features/oauth_http_mac.rb
108
116
  - lib/rodauth/features/oauth_implicit_grant.rb
109
117
  - lib/rodauth/features/oauth_jwt.rb
110
118
  - lib/rodauth/features/oauth_jwt_bearer_grant.rb
119
+ - lib/rodauth/features/oauth_management_base.rb
111
120
  - lib/rodauth/features/oauth_pkce.rb
112
121
  - lib/rodauth/features/oauth_resource_server.rb
113
122
  - lib/rodauth/features/oauth_saml_bearer_grant.rb
@@ -115,8 +124,10 @@ files:
115
124
  - lib/rodauth/features/oauth_token_management.rb
116
125
  - lib/rodauth/features/oauth_token_revocation.rb
117
126
  - lib/rodauth/features/oidc.rb
127
+ - lib/rodauth/features/oidc_dynamic_client_registration.rb
118
128
  - lib/rodauth/oauth.rb
119
129
  - lib/rodauth/oauth/database_extensions.rb
130
+ - lib/rodauth/oauth/jwe_extensions.rb
120
131
  - lib/rodauth/oauth/railtie.rb
121
132
  - lib/rodauth/oauth/refinements.rb
122
133
  - lib/rodauth/oauth/ttl_store.rb
@@ -128,7 +139,7 @@ files:
128
139
  - templates/device_search.str
129
140
  - templates/device_verification.str
130
141
  - templates/homepage_url_field.str
131
- - templates/jws_jwk_field.str
142
+ - templates/jwks_field.str
132
143
  - templates/jwt_public_key_field.str
133
144
  - templates/name_field.str
134
145
  - templates/new_oauth_application.str
@@ -1,4 +0,0 @@
1
- <div class="form-group">
2
- <label for="name">#{rodauth.oauth_applications_jws_jwk_label}#{rodauth.input_field_label_suffix}</label>
3
- #{rodauth.input_field_string(rodauth.oauth_application_jws_jwk_param, "jws_jwk", :type=>"text")}
4
- </div>