%%%------------------------------------------------------------------- %% @doc Logout from the OpenID Provider %% @end %% @since 3.0.0 %%%------------------------------------------------------------------- -module(oidcc_logout). -feature(maybe_expr, enable). -include("oidcc_client_context.hrl"). -include("oidcc_provider_configuration.hrl"). -include("oidcc_token.hrl"). -export([initiate_url/3]). -export_type([error/0]). -export_type([initiate_url_opts/0]). -type error() :: end_session_endpoint_not_supported. -type initiate_url_opts() :: #{ logout_hint => binary(), post_logout_redirect_uri => uri_string:uri_string(), state => binary(), ui_locales => binary(), extra_query_params => oidcc_http_util:query_params() }. %% Configure Relaying Party initiated Logout URI %% %% See [https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout] %% %%

Parameters

%% %% %% @doc %% Initiate URI for Relaying Party initiated Logout %% %% See [https://openid.net/specs/openid-connect-rpinitiated-1_0.html#RPLogout] %% %% For a high level interface using {@link oidcc_provider_configuration_worker} %% see {@link oidcc:initiate_logout_url/4}. %% %%

Examples

%% %% ``` %% {ok, ClientContext} = oidcc_client_context:from_configuration_worker( %% provider_name, %% <<"client_id">>, %% unauthenticated %% ), %% %% %% Get `Token` from `oidcc_token` %% %% {ok, RedirectUri} = %% oidcc_logout:initiate_url( %% Token, %% ClientContext, %% #{post_logout_redirect_uri: <<"https://my.server/return"} %% ), %% %% %% RedirectUri = https://my.provider/logout?id_token_hint=IDToken&client_id=ClientId&post_logout_redirect_uri=https%3A%2F%2Fmy.server%2Freturn %% ''' %% @end %% @since 3.0.0 -spec initiate_url(Token, ClientContext, Opts) -> {ok, uri_string:uri_string()} | {error, error()} when Token :: IdToken | oidcc_token:t() | undefined, IdToken :: binary(), ClientContext :: oidcc_client_context:t(), Opts :: initiate_url_opts(). initiate_url(#oidcc_token{id = #oidcc_token_id{token = IdToken}}, ClientContext, Opts) -> initiate_url(IdToken, ClientContext, Opts); initiate_url(IdToken, ClientContext, Opts) -> #oidcc_client_context{ provider_configuration = Configuration, client_id = ClientId } = ClientContext, #oidcc_provider_configuration{end_session_endpoint = EndSessionEndpoint} = Configuration, QueryParams0 = [ {"id_token_hint", IdToken}, {"logout_hint", maps:get(logout_hint, Opts, undefined)}, {"client_id", ClientId}, {"post_logout_redirect_uri", maps:get(post_logout_redirect_uri, Opts, undefined)}, {"state", maps:get(state, Opts, undefined)}, {"ui_locales", maps:get(ui_locales, Opts, undefined)} | maps:get(extra_query_params, Opts, []) ], QueryParams1 = lists:filter( fun ({_Name, undefined}) -> false; ({_Name, _Value}) -> true end, QueryParams0 ), case EndSessionEndpoint of undefined -> {error, end_session_endpoint_not_supported}; Uri0 -> UriMap0 = uri_string:parse(Uri0), QueryString0 = maps:get(query, UriMap0, <<"">>), QueryParams = uri_string:dissect_query(QueryString0) ++ QueryParams1, QueryString = uri_string:compose_query(QueryParams), UriMap = maps:put(query, QueryString, UriMap0), Uri = uri_string:recompose(UriMap), {ok, Uri} end.