rodauth-oauth 1.3.2 → 1.4.0
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 +17 -10
- data/doc/release_notes/1_4_0.md +49 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize.html.erb +23 -23
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/frontchannel_logout.html.erb +10 -0
- data/lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_applications.html.erb +1 -1
- data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +20 -0
- data/lib/generators/rodauth/oauth/views_generator.rb +2 -2
- data/lib/rodauth/features/oauth_application_management.rb +1 -1
- data/lib/rodauth/features/oauth_assertion_base.rb +1 -1
- data/lib/rodauth/features/oauth_authorize_base.rb +1 -1
- data/lib/rodauth/features/oauth_base.rb +31 -30
- data/lib/rodauth/features/oauth_device_code_grant.rb +2 -2
- data/lib/rodauth/features/oauth_dynamic_client_registration.rb +1 -0
- data/lib/rodauth/features/oauth_grant_management.rb +1 -1
- data/lib/rodauth/features/oauth_jwt.rb +3 -3
- data/lib/rodauth/features/oauth_jwt_base.rb +15 -10
- data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +1 -1
- data/lib/rodauth/features/oauth_jwt_jwks.rb +1 -1
- data/lib/rodauth/features/oauth_resource_server.rb +1 -1
- data/lib/rodauth/features/oauth_saml_bearer_grant.rb +79 -47
- data/lib/rodauth/features/oauth_tls_client_auth.rb +1 -1
- data/lib/rodauth/features/oauth_token_introspection.rb +1 -1
- data/lib/rodauth/features/oauth_token_revocation.rb +1 -1
- data/lib/rodauth/features/oidc.rb +27 -8
- data/lib/rodauth/features/oidc_backchannel_logout.rb +120 -0
- data/lib/rodauth/features/oidc_dynamic_client_registration.rb +25 -0
- data/lib/rodauth/features/oidc_frontchannel_logout.rb +134 -0
- data/lib/rodauth/features/oidc_logout_base.rb +76 -0
- data/lib/rodauth/features/oidc_rp_initiated_logout.rb +29 -6
- data/lib/rodauth/features/oidc_session_management.rb +89 -0
- data/lib/rodauth/oauth/http_extensions.rb +1 -1
- data/lib/rodauth/oauth/version.rb +1 -1
- data/locales/en.yml +9 -0
- data/locales/pt.yml +9 -0
- data/templates/check_session.str +67 -0
- data/templates/frontchannel_logout.str +17 -0
- metadata +11 -2
@@ -4,11 +4,15 @@ require "rodauth/oauth"
|
|
4
4
|
|
5
5
|
module Rodauth
|
6
6
|
Feature.define(:oidc_rp_initiated_logout, :OidcRpInitiatedLogout) do
|
7
|
-
depends :
|
7
|
+
depends :oidc_logout_base
|
8
|
+
response "oidc_logout"
|
8
9
|
|
9
10
|
auth_value_method :oauth_applications_post_logout_redirect_uris_column, :post_logout_redirect_uris
|
11
|
+
translatable_method :oauth_invalid_id_token_hint_message, "Invalid ID token hint"
|
10
12
|
translatable_method :oauth_invalid_post_logout_redirect_uri_message, "Invalid post logout redirect URI"
|
11
13
|
|
14
|
+
attr_reader :oidc_logout_redirect
|
15
|
+
|
12
16
|
# /oidc-logout
|
13
17
|
auth_server_route(:oidc_logout) do |r|
|
14
18
|
require_authorizable_account
|
@@ -19,7 +23,7 @@ module Rodauth
|
|
19
23
|
catch_error do
|
20
24
|
validate_oidc_logout_params
|
21
25
|
|
22
|
-
oauth_application = nil
|
26
|
+
claims = oauth_application = nil
|
23
27
|
|
24
28
|
if (id_token_hint = param_or_nil("id_token_hint"))
|
25
29
|
#
|
@@ -32,7 +36,12 @@ module Rodauth
|
|
32
36
|
#
|
33
37
|
claims = jwt_decode(id_token_hint, verify_claims: false)
|
34
38
|
|
35
|
-
redirect_logout_with_error(
|
39
|
+
redirect_logout_with_error(oauth_invalid_id_token_hint_message) unless claims
|
40
|
+
|
41
|
+
# If the ID Token's sid claim does not correspond to the RP's current session or a
|
42
|
+
# recent session at the OP, the OP SHOULD treat the logout request as suspect, and
|
43
|
+
# MAY decline to act upon it.
|
44
|
+
redirect_logout_with_error(oauth_invalid_client_message) if claims["sid"] && !active_sessions?(claims["sid"])
|
36
45
|
|
37
46
|
oauth_application = db[oauth_applications_table].where(oauth_applications_client_id_column => claims["aud"]).first
|
38
47
|
oauth_grant = db[oauth_grants_table]
|
@@ -40,9 +49,15 @@ module Rodauth
|
|
40
49
|
.where(oauth_grants_oauth_application_id_column => oauth_application[oauth_applications_id_column])
|
41
50
|
.first
|
42
51
|
|
52
|
+
unique_account_id = if oauth_grant
|
53
|
+
oauth_grant[oauth_grants_account_id_column]
|
54
|
+
else
|
55
|
+
account_id
|
56
|
+
end
|
57
|
+
|
43
58
|
# check whether ID token belongs to currently logged-in user
|
44
|
-
redirect_logout_with_error(oauth_invalid_client_message) unless
|
45
|
-
|
59
|
+
redirect_logout_with_error(oauth_invalid_client_message) unless claims["sub"] == jwt_subject(unique_account_id,
|
60
|
+
oauth_application)
|
46
61
|
|
47
62
|
# When an id_token_hint parameter is present, the OP MUST validate that it was the issuer of the ID Token.
|
48
63
|
redirect_logout_with_error(oauth_invalid_client_message) unless claims && claims["iss"] == oauth_jwt_issuer
|
@@ -59,6 +74,8 @@ module Rodauth
|
|
59
74
|
|
60
75
|
if (post_logout_redirect_uri = param_or_nil("post_logout_redirect_uri"))
|
61
76
|
error_message = catch(:default_logout_redirect) do
|
77
|
+
throw(:default_logout_redirect, oauth_invalid_id_token_hint_message) unless claims
|
78
|
+
|
62
79
|
oauth_application = db[oauth_applications_table].where(oauth_applications_client_id_column => claims["client_id"]).first
|
63
80
|
|
64
81
|
throw(:default_logout_redirect, oauth_invalid_client_message) unless oauth_application
|
@@ -78,7 +95,9 @@ module Rodauth
|
|
78
95
|
post_logout_redirect_uri = post_logout_redirect_uri.to_s
|
79
96
|
end
|
80
97
|
|
81
|
-
|
98
|
+
@oidc_logout_redirect = post_logout_redirect_uri
|
99
|
+
|
100
|
+
require_response(:_oidc_logout_response)
|
82
101
|
end
|
83
102
|
|
84
103
|
end
|
@@ -90,6 +109,10 @@ module Rodauth
|
|
90
109
|
end
|
91
110
|
end
|
92
111
|
|
112
|
+
def _oidc_logout_response
|
113
|
+
redirect(oidc_logout_redirect)
|
114
|
+
end
|
115
|
+
|
93
116
|
private
|
94
117
|
|
95
118
|
# Logout
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rodauth/oauth"
|
4
|
+
|
5
|
+
module Rodauth
|
6
|
+
Feature.define(:oidc_session_management, :OidcSessionManagement) do
|
7
|
+
depends :oidc
|
8
|
+
|
9
|
+
view "check_session", "Check Session", "check_session"
|
10
|
+
|
11
|
+
auth_value_method :oauth_oidc_user_agent_state_cookie_key, "_rodauth_oauth_user_agent_state"
|
12
|
+
auth_value_method :oauth_oidc_user_agent_state_cookie_options, {}.freeze
|
13
|
+
auth_value_method :oauth_oidc_user_agent_state_cookie_expires_in, 365 * 24 * 60 * 60 # 1 year
|
14
|
+
|
15
|
+
auth_value_method :oauth_oidc_user_agent_state_js, nil
|
16
|
+
|
17
|
+
auth_value_methods(
|
18
|
+
:oauth_oidc_session_management_salt
|
19
|
+
)
|
20
|
+
# /authorize
|
21
|
+
auth_server_route(:check_session) do |r|
|
22
|
+
allow_cors(r)
|
23
|
+
|
24
|
+
r.get do
|
25
|
+
set_title(:check_session_page_title)
|
26
|
+
scope.view(_view_opts("check_session").merge(layout: false))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def clear_session
|
31
|
+
super
|
32
|
+
|
33
|
+
# update user agent state in the process
|
34
|
+
# TODO: dangerous if this gets overidden by the user
|
35
|
+
|
36
|
+
user_agent_state_cookie_opts = Hash[oauth_oidc_user_agent_state_cookie_options]
|
37
|
+
user_agent_state_cookie_opts[:value] = oauth_unique_id_generator
|
38
|
+
user_agent_state_cookie_opts[:expires] = convert_timestamp(Time.now + oauth_oidc_user_agent_state_cookie_expires_in)
|
39
|
+
user_agent_state_cookie_opts[:secure] = true
|
40
|
+
::Rack::Utils.set_cookie_header!(response.headers, oauth_oidc_user_agent_state_cookie_key, user_agent_state_cookie_opts)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def do_authorize(*)
|
46
|
+
params, mode = super
|
47
|
+
|
48
|
+
params["session_state"] = generate_session_state
|
49
|
+
|
50
|
+
[params, mode]
|
51
|
+
end
|
52
|
+
|
53
|
+
def response_error_params(*)
|
54
|
+
payload = super
|
55
|
+
|
56
|
+
return payload unless request.path == authorize_path
|
57
|
+
|
58
|
+
payload["session_state"] = generate_session_state
|
59
|
+
payload
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_session_state
|
63
|
+
salt = oauth_oidc_session_management_salt
|
64
|
+
|
65
|
+
uri = URI(redirect_uri)
|
66
|
+
origin = if uri.respond_to?(:origin)
|
67
|
+
uri.origin
|
68
|
+
else
|
69
|
+
# TODO: remove when not supporting uri < 0.11
|
70
|
+
"#{uri.scheme}://#{uri.host}#{":#{uri.port}" if uri.port != uri.default_port}"
|
71
|
+
end
|
72
|
+
session_id = "#{oauth_application[oauth_applications_client_id_column]} " \
|
73
|
+
"#{origin} " \
|
74
|
+
"#{request.cookies[oauth_oidc_user_agent_state_cookie_key]} #{salt}"
|
75
|
+
|
76
|
+
"#{Digest::SHA256.hexdigest(session_id)}.#{salt}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def oauth_server_metadata_body(*)
|
80
|
+
super.tap do |data|
|
81
|
+
data[:check_session_iframe] = check_session_url
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def oauth_oidc_session_management_salt
|
86
|
+
oauth_unique_id_generator
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/locales/en.yml
CHANGED
@@ -8,7 +8,9 @@ en:
|
|
8
8
|
device_verification_notice_flash: "The device is verified"
|
9
9
|
user_code_not_found_error_flash: "No device to authorize with the given user code"
|
10
10
|
authorize_page_title: "Authorize"
|
11
|
+
frontchannel_logout_page_title: "Logout"
|
11
12
|
authorize_page_lead: "The application %{name} would like to access your data."
|
13
|
+
oauth_frontchannel_logout_redirecting_lead: "You are being redirected..."
|
12
14
|
authorize_error_page_title: "Authorize Error"
|
13
15
|
oauth_cancel_button: "Cancel"
|
14
16
|
oauth_applications_page_title: "Oauth Applications"
|
@@ -18,6 +20,7 @@ en:
|
|
18
20
|
oauth_grants_page_title: "My Oauth Grants"
|
19
21
|
device_verification_page_title: "Device Verification"
|
20
22
|
device_search_page_title: "Device Search"
|
23
|
+
check_session_page_title: "Check Session"
|
21
24
|
oauth_management_pagination_previous_button: "Previous"
|
22
25
|
oauth_management_pagination_next_button: "Next"
|
23
26
|
oauth_grants_type_label: "Grant Type"
|
@@ -41,6 +44,8 @@ en:
|
|
41
44
|
oauth_grant_user_code_label: "User code"
|
42
45
|
oauth_grant_user_jws_jwk_label: "JSON Web Keys"
|
43
46
|
oauth_grant_user_jwt_public_key_label: "Public key"
|
47
|
+
oauth_frontchannel_logout_redirecting_label: "please click %{link} if your browser does not redirect you in a few seconds."
|
48
|
+
oauth_frontchannel_logout_redirecting_link_label: "here"
|
44
49
|
oauth_application_button: "Register"
|
45
50
|
oauth_authorize_button: "Authorize"
|
46
51
|
oauth_grant_revoke_button: "Revoke"
|
@@ -68,3 +73,7 @@ en:
|
|
68
73
|
oauth_invalid_scope_message: "The Access Token expired"
|
69
74
|
oauth_authorize_parameter_required: "Invalid or missing '%{parameter}'"
|
70
75
|
oauth_invalid_post_logout_redirect_uri_message: "Invalid post logout redirect URI"
|
76
|
+
oauth_saml_assertion_not_base64_message: "SAML assertion must be in base64 format"
|
77
|
+
oauth_saml_assertion_single_issuer_message: "SAML assertion must have a single issuer"
|
78
|
+
oauth_saml_settings_not_found_message: "No SAML settings found for issuer"
|
79
|
+
oauth_invalid_id_token_hint_message: "Invalid ID token hint"
|
data/locales/pt.yml
CHANGED
@@ -8,7 +8,9 @@ pt:
|
|
8
8
|
device_verification_notice_flash: "O dispositivo foi verificado com sucesso"
|
9
9
|
user_code_not_found_error_flash: "Não existe nenhum dispositivo a ser autorizado com o código de usuário inserido"
|
10
10
|
authorize_page_title: "Autorizar"
|
11
|
+
frontchannel_logout_page_title: "Saindo"
|
11
12
|
authorize_page_lead: "O aplicativo %{name} gostaria de aceder aos seus dados."
|
13
|
+
oauth_frontchannel_logout_redirecting_lead: "Redireccionando.."
|
12
14
|
authorize_error_page_title: Erro de autorização
|
13
15
|
oauth_cancel_button: "Cancelar"
|
14
16
|
oauth_applications_page_title: "Aplicativos OAuth"
|
@@ -18,6 +20,7 @@ pt:
|
|
18
20
|
oauth_grants_page_title: "As minhas concessões Oauth"
|
19
21
|
device_verification_page_title: "Verificação de dispositivo"
|
20
22
|
device_search_page_title: "Pesquisa de dispositivo"
|
23
|
+
check_session_page_title: "Verificação de Sessão"
|
21
24
|
oauth_management_pagination_previous_button: "Anterior"
|
22
25
|
oauth_management_pagination_next_button: "Próxima"
|
23
26
|
oauth_grants_type_label: "Tipo de concessão"
|
@@ -41,6 +44,8 @@ pt:
|
|
41
44
|
oauth_grant_user_code_label: "Código do usuário"
|
42
45
|
oauth_grant_user_jws_jwk_label: "Chaves JSON Web"
|
43
46
|
oauth_grant_user_jwt_public_key_label: "Chave pública"
|
47
|
+
oauth_frontchannel_logout_redirecting_label: "por favor clique %{link} se o seu navegador não lhe redireccionar em alguns segundos."
|
48
|
+
oauth_frontchannel_logout_redirecting_link_label: "aqui"
|
44
49
|
oauth_application_button: "Registar"
|
45
50
|
oauth_authorize_button: "Autorizar"
|
46
51
|
oauth_grant_revoke_button: "Revogar"
|
@@ -68,3 +73,7 @@ pt:
|
|
68
73
|
oauth_invalid_scope_message: "O Token de acesso expirou"
|
69
74
|
oauth_authorize_parameter_required: "'%{parameter}' inválido ou em falta"
|
70
75
|
oauth_invalid_post_logout_redirect_uri_message: "URI de redireccionamento pós-logout inválido"
|
76
|
+
oauth_saml_assertion_not_base64_message: "A asserção SAML tem que estar no formato base64"
|
77
|
+
oauth_saml_assertion_single_issuer_message: "A asserção SAML tem que ter um único emissor"
|
78
|
+
oauth_saml_settings_not_found_message: "Nenhuma configuração SAML encontrada para o emissor"
|
79
|
+
oauth_invalid_id_token_hint_message: "ID token hint inválido"
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6
|
+
<title>#{@page_title}</title>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<script type="text/javascript">
|
10
|
+
window.addEventListener("message", receiveMessage, false);
|
11
|
+
|
12
|
+
function receiveMessage(e) { // e.data has client_id and session_state
|
13
|
+
var client_id = e.data.substr(0, e.data.lastIndexOf(' '));
|
14
|
+
var session_state = e.data.substr(e.data.lastIndexOf(' ') + 1);
|
15
|
+
var salt = session_state.split('.')[1];
|
16
|
+
|
17
|
+
if (!client_id || !session_state || !salt) {
|
18
|
+
postMessage('error', e.origin);
|
19
|
+
return;
|
20
|
+
}
|
21
|
+
|
22
|
+
#{rodauth.oauth_oidc_user_agent_state_js}
|
23
|
+
|
24
|
+
// get_op_user_agent_state() is an OP defined function
|
25
|
+
// that returns the User Agent's login status at the OP.
|
26
|
+
// How it is done is entirely up to the OP.
|
27
|
+
var opuas = getOpUserAgentState();
|
28
|
+
|
29
|
+
// Here, the session_state is calculated in this particular way,
|
30
|
+
// but it is entirely up to the OP how to do it under the
|
31
|
+
// requirements defined in this specification.
|
32
|
+
var msgBuffer = new TextEncoder('utf-8').encode(client_id + ' ' + e.origin + ' ' + opuas + ' ' + salt);
|
33
|
+
crypto.subtle.digest('SHA-256', msgBuffer).then(function(hash) {
|
34
|
+
var hashArray = Array.from(new Uint8Array(hash)); // convert buffer to byte array
|
35
|
+
var hashHex = hashArray
|
36
|
+
.map(function(b) { return b.toString(16).padStart(2, "0"); })
|
37
|
+
.join("");
|
38
|
+
var ss = hashHex + "." + salt;
|
39
|
+
|
40
|
+
var stat = '';
|
41
|
+
if (session_state === ss) {
|
42
|
+
stat = 'unchanged';
|
43
|
+
} else {
|
44
|
+
stat = 'changed';
|
45
|
+
}
|
46
|
+
|
47
|
+
e.source.postMessage(stat, e.origin);
|
48
|
+
});
|
49
|
+
};
|
50
|
+
|
51
|
+
function getOpUserAgentState() {
|
52
|
+
var name = "#{rodauth.oauth_oidc_user_agent_state_cookie_key}=";
|
53
|
+
var ca = document.cookie.split(';');
|
54
|
+
var value = null;
|
55
|
+
for (var i = 0; i < ca.length; i++) {
|
56
|
+
var c = ca[i].trim();
|
57
|
+
if ((c.indexOf(name)) == 0) {
|
58
|
+
value = c.substr(name.length);
|
59
|
+
break;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
return value;
|
64
|
+
}
|
65
|
+
</script>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="mb-3">
|
2
|
+
<h1>#{rodauth.oauth_frontchannel_logout_redirecting_lead}</h1>
|
3
|
+
<p>
|
4
|
+
#{
|
5
|
+
rodauth.oauth_frontchannel_logout_redirecting_label(
|
6
|
+
link: "<a href=\"#{rodauth.frontchannel_logout_redirect}\">" \
|
7
|
+
"#{rodauth.oauth_frontchannel_logout_redirecting_link_label}</a>"
|
8
|
+
)
|
9
|
+
}
|
10
|
+
</p>
|
11
|
+
#{
|
12
|
+
rodauth.frontchannel_logout_urls.map do |logout_url|
|
13
|
+
"<iframe src=\"#{logout_url}\"></iframe>"
|
14
|
+
end.join
|
15
|
+
}
|
16
|
+
</div>
|
17
|
+
<meta http-equiv="refresh" content="#{rodauth.frontchannel_logout_redirect_timeout}; URL=#{rodauth.frontchannel_logout_redirect}" />
|
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: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Cardoso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rodauth
|
@@ -72,6 +72,7 @@ extra_rdoc_files:
|
|
72
72
|
- doc/release_notes/1_3_0.md
|
73
73
|
- doc/release_notes/1_3_1.md
|
74
74
|
- doc/release_notes/1_3_2.md
|
75
|
+
- doc/release_notes/1_4_0.md
|
75
76
|
files:
|
76
77
|
- CHANGELOG.md
|
77
78
|
- LICENSE.txt
|
@@ -115,6 +116,7 @@ files:
|
|
115
116
|
- doc/release_notes/1_3_0.md
|
116
117
|
- doc/release_notes/1_3_1.md
|
117
118
|
- doc/release_notes/1_3_2.md
|
119
|
+
- doc/release_notes/1_4_0.md
|
118
120
|
- lib/generators/rodauth/oauth/install_generator.rb
|
119
121
|
- lib/generators/rodauth/oauth/templates/app/models/oauth_application.rb
|
120
122
|
- lib/generators/rodauth/oauth/templates/app/models/oauth_grant.rb
|
@@ -122,6 +124,7 @@ files:
|
|
122
124
|
- lib/generators/rodauth/oauth/templates/app/views/rodauth/authorize_error.erb
|
123
125
|
- lib/generators/rodauth/oauth/templates/app/views/rodauth/device_search.html.erb
|
124
126
|
- lib/generators/rodauth/oauth/templates/app/views/rodauth/device_verification.html.erb
|
127
|
+
- lib/generators/rodauth/oauth/templates/app/views/rodauth/frontchannel_logout.html.erb
|
125
128
|
- lib/generators/rodauth/oauth/templates/app/views/rodauth/new_oauth_application.html.erb
|
126
129
|
- lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application.html.erb
|
127
130
|
- lib/generators/rodauth/oauth/templates/app/views/rodauth/oauth_application_oauth_grants.html.erb
|
@@ -155,9 +158,13 @@ files:
|
|
155
158
|
- lib/rodauth/features/oauth_token_introspection.rb
|
156
159
|
- lib/rodauth/features/oauth_token_revocation.rb
|
157
160
|
- lib/rodauth/features/oidc.rb
|
161
|
+
- lib/rodauth/features/oidc_backchannel_logout.rb
|
158
162
|
- lib/rodauth/features/oidc_dynamic_client_registration.rb
|
163
|
+
- lib/rodauth/features/oidc_frontchannel_logout.rb
|
164
|
+
- lib/rodauth/features/oidc_logout_base.rb
|
159
165
|
- lib/rodauth/features/oidc_rp_initiated_logout.rb
|
160
166
|
- lib/rodauth/features/oidc_self_issued.rb
|
167
|
+
- lib/rodauth/features/oidc_session_management.rb
|
161
168
|
- lib/rodauth/oauth.rb
|
162
169
|
- lib/rodauth/oauth/database_extensions.rb
|
163
170
|
- lib/rodauth/oauth/http_extensions.rb
|
@@ -169,10 +176,12 @@ files:
|
|
169
176
|
- locales/pt.yml
|
170
177
|
- templates/authorize.str
|
171
178
|
- templates/authorize_error.str
|
179
|
+
- templates/check_session.str
|
172
180
|
- templates/client_secret_field.str
|
173
181
|
- templates/description_field.str
|
174
182
|
- templates/device_search.str
|
175
183
|
- templates/device_verification.str
|
184
|
+
- templates/frontchannel_logout.str
|
176
185
|
- templates/homepage_url_field.str
|
177
186
|
- templates/jwks_field.str
|
178
187
|
- templates/name_field.str
|