rodauth-oauth 0.8.0 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
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>