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.
- checksums.yaml +4 -4
- data/README.md +6 -3
- data/doc/release_notes/0_9_0.md +56 -0
- data/doc/release_notes/0_9_1.md +9 -0
- data/doc/release_notes/0_9_2.md +10 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +22 -1
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb +8 -3
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb +8 -2
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_tokens.html.erb +1 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +1 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_tokens.html.erb +1 -0
- data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +13 -1
- data/lib/rodauth/features/oauth.rb +2 -2
- data/lib/rodauth/features/oauth_application_management.rb +23 -7
- data/lib/rodauth/features/oauth_assertion_base.rb +1 -1
- data/lib/rodauth/features/oauth_authorization_code_grant.rb +4 -1
- data/lib/rodauth/features/oauth_base.rb +57 -14
- data/lib/rodauth/features/oauth_client_credentials_grant.rb +33 -0
- data/lib/rodauth/features/oauth_device_grant.rb +4 -5
- data/lib/rodauth/features/oauth_dynamic_client_registration.rb +252 -0
- data/lib/rodauth/features/oauth_jwt.rb +251 -49
- data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +1 -0
- data/lib/rodauth/features/oauth_management_base.rb +72 -0
- data/lib/rodauth/features/oauth_pkce.rb +1 -1
- data/lib/rodauth/features/oauth_token_management.rb +8 -6
- data/lib/rodauth/features/oidc.rb +37 -7
- data/lib/rodauth/features/oidc_dynamic_client_registration.rb +147 -0
- data/lib/rodauth/oauth/jwe_extensions.rb +64 -0
- data/lib/rodauth/oauth/ttl_store.rb +9 -3
- data/lib/rodauth/oauth/version.rb +1 -1
- data/locales/en.yml +6 -1
- data/templates/authorize.str +50 -1
- data/templates/jwks_field.str +4 -0
- data/templates/jwt_public_key_field.str +1 -1
- data/templates/new_oauth_application.str +1 -1
- data/templates/oauth_application.str +1 -1
- data/templates/oauth_application_oauth_tokens.str +1 -0
- data/templates/oauth_applications.str +1 -0
- data/templates/oauth_tokens.str +1 -0
- data/templates/scope_field.str +3 -2
- metadata +14 -3
- 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
|
-
|
29
|
-
|
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]
|
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)
|
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: "
|
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"
|
data/templates/authorize.str
CHANGED
@@ -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
|
-
|
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>
|
@@ -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>
|
@@ -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[
|
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>" +
|
data/templates/oauth_tokens.str
CHANGED
data/templates/scope_field.str
CHANGED
@@ -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
|
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.
|
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-
|
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/
|
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
|
data/templates/jws_jwk_field.str
DELETED