# `oidcc_client_context`
[🔗](https://github.com/erlef/oidcc/blob/ee3434ddec86c14471af8f8a8f159971e654da3c
/src/oidcc_client_context.erl#L4)

Client Configuration for authorization, token exchange, and userinfo.

For most projects, it makes sense to use `m:oidcc_provider_configuration_worker` and the high-level
interface of `oidcc`. In that case, direct usage of this module is not needed.

To use the record, import the definition:

```erlang
-include_lib(["oidcc/include/oidcc_client_context.hrl"]).
```

# `authenticated_opts`
*since 3.0.0* 

```elixir
-type authenticated_opts() :: #{client_jwks => jose_jwk:key()}.
```

# `authenticated_t`
*since 3.0.0* 

```elixir
-type authenticated_t() ::
          #oidcc_client_context{provider_configuration :: oidcc_provider_configuration:t(),
                                jwks :: jose_jwk:key(),
                                client_id :: binary(),
                                client_secret :: binary(),
                                client_jwks :: jose_jwk:key() | none}.
```

# `error`
*since 3.0.0* 

```elixir
-type error() :: provider_not_ready.
```

# `opts`
*since 3.0.0* 

```elixir
-type opts() :: authenticated_opts() | unauthenticated_opts().
```

# `t`
*since 3.0.0* 

```elixir
-type t() :: authenticated_t() | unauthenticated_t().
```

# `unauthenticated_opts`
*since 3.0.0* 

```elixir
-type unauthenticated_opts() :: #{}.
```

# `unauthenticated_t`
*since 3.0.0* 

```elixir
-type unauthenticated_t() ::
          #oidcc_client_context{provider_configuration :: oidcc_provider_configuration:t(),
                                jwks :: jose_jwk:key(),
                                client_id :: binary(),
                                client_secret :: unauthenticated,
                                client_jwks :: none}.
```

# `apply_profiles`
*since 3.2.0* 

```elixir
-spec apply_profiles(ClientContext, oidcc_profile:opts()) ->
                        {ok, ClientContext, oidcc_profile:opts_no_profiles()} |
                        {error, oidcc_profile:error()}
                        when ClientContext :: oidcc_client_context:t().
```

Apply OpenID Connect / OAuth2 Profiles to the context.

Currently, the only supported profiles are:
- `fapi2_security_profile` - https://openid.bitbucket.io/fapi/fapi-2_0-security-profile.html
- `fapi2_message_signing` - https://openid.bitbucket.io/fapi/fapi-2_0-message-signing.html

It returns an updated `t:t/0` record and a map of options to
be merged into the `m:oidcc_authorization` and `m:oidcc_token` functions.

## Examples

```erlang
ClientContext = #oidcc_client_context{} = oidcc_client_context:from_...(...),

{#oidcc_client_context{} = ClientContext1, Opts} = oidcc_client_context:apply_profiles(
  ClientContext,
  #{
    profiles => [fapi2_message_signing]
  }),

{ok, Uri} = oidcc_authorization:create_redirect_uri(
  ClientContext1,
  maps:merge(Opts, #{...})
).
```

# `from_configuration_worker`
*since 3.0.0* 

```elixir
-spec from_configuration_worker(ProviderName, ClientId, ClientSecret) ->
                                   {ok, authenticated_t()} | {error, error()}
                                   when
                                       ProviderName :: gen_server:server_ref(),
                                       ClientId :: binary(),
                                       ClientSecret :: binary();
                               (ProviderName, ClientId, ClientSecret) ->
                                   {ok, unauthenticated_t()} | {error, error()}
                                   when
                                       ProviderName :: gen_server:server_ref(),
                                       ClientId :: binary(),
                                       ClientSecret :: unauthenticated.
```

Create Client Context from a `m:oidcc_provider_configuration_worker`.

See `from_configuration_worker/4`.

# `from_configuration_worker`
*since 3.0.0* 

```elixir
-spec from_configuration_worker(ProviderName, ClientId, ClientSecret, Opts) ->
                                   {ok, authenticated_t()} | {error, error()}
                                   when
                                       ProviderName :: gen_server:server_ref(),
                                       ClientId :: binary(),
                                       ClientSecret :: binary(),
                                       Opts :: authenticated_opts();
                               (ProviderName, ClientId, ClientSecret, Opts) ->
                                   {ok, unauthenticated_t()} | {error, error()}
                                   when
                                       ProviderName :: gen_server:server_ref(),
                                       ClientId :: binary(),
                                       ClientSecret :: unauthenticated,
                                       Opts :: unauthenticated_opts().
```

Create Client Context from a `m:oidcc_provider_configuration_worker`.

## Examples

```erlang
{ok, Pid} =
  oidcc_provider_configuration_worker:start_link(#{
    issuer => <<"https://login.salesforce.com">>
  }),

{ok, #oidcc_client_context{}} =
  oidcc_client_context:from_configuration_worker(Pid,
                                                 <<"client_id">>,
                                                 <<"client_secret">>).
```

```erlang
{ok, Pid} =
  oidcc_provider_configuration_worker:start_link(#{
    issuer => <<"https://login.salesforce.com">>,
    name => {local, salesforce_provider}
  }),

{ok, #oidcc_client_context{}} =
  oidcc_client_context:from_configuration_worker(
    salesforce_provider,
    <<"client_id">>,
    <<"client_secret">>,
    #{client_jwks => jose_jwk:generate_key(16)}
  ).
```

# `from_manual`
*since 3.0.0* 

```elixir
-spec from_manual(Configuration, Jwks, ClientId, ClientSecret) -> authenticated_t()
                     when
                         Configuration :: oidcc_provider_configuration:t(),
                         Jwks :: jose_jwk:key(),
                         ClientId :: binary(),
                         ClientSecret :: binary();
                 (Configuration, Jwks, ClientId, ClientSecret) -> unauthenticated_t()
                     when
                         Configuration :: oidcc_provider_configuration:t(),
                         Jwks :: jose_jwk:key(),
                         ClientId :: binary(),
                         ClientSecret :: unauthenticated.
```

Create Client Context manually.

See `from_manual/5`.

# `from_manual`
*since 3.0.0* 

```elixir
-spec from_manual(Configuration, Jwks, ClientId, ClientSecret, Opts) -> authenticated_t()
                     when
                         Configuration :: oidcc_provider_configuration:t(),
                         Jwks :: jose_jwk:key(),
                         ClientId :: binary(),
                         ClientSecret :: binary(),
                         Opts :: authenticated_opts();
                 (Configuration, Jwks, ClientId, ClientSecret, Opts) -> unauthenticated_t()
                     when
                         Configuration :: oidcc_provider_configuration:t(),
                         Jwks :: jose_jwk:key(),
                         ClientId :: binary(),
                         ClientSecret :: unauthenticated,
                         Opts :: unauthenticated_opts().
```

Create Client Context manually.

## Examples

```erlang
{ok, Configuration} =
  oidcc_provider_configuration:load_configuration(<<"https://login.salesforce.com">>, []),

#oidcc_provider_configuration{jwks_uri = JwksUri} = Configuration,

{ok, Jwks} = oidcc_provider_configuration:load_jwks(JwksUri, []).

#oidcc_client_context{} =
  oidcc_client_context:from_manual(
    Metadata,
    Jwks,
    <<"client_id">>,
    <<"client_secret">>,
    #{client_jwks => jose_jwk:generate_key(16)}
  ).
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
