KindeClientSDK (kinde_sdk v1.0.0)
Kinde Client supporting client_credentials
, authorization_code
and pkce
OAuth2 methods,
providing authentication functionalities to your Kinde business.
configuration
Configuration
api-keys
API Keys
You can set your keys in your application configuration. Use config/config.exs
.
For example:
config :kinde_sdk,
backend_client_id: "test_x1y2z3a1",
frontend_client_id: "test_a1b2c3d4",
client_secret: "test_112233",
redirect_url: "http://text.com/callback",
domain: "https://test.kinde.com",
logout_redirect_url: "http://text.com/logout"
Optionally, you can also set scope
as well.
config :kinde_sdk,
scope: "email"
You can also use System.get_env/1
to retrieve the API key from
an environment variables. For example:
config :kinde_sdk,
backend_client_id: System.get_env("KINDE_BACKEND_CLIENT_ID")
usage
Usage
Initialize your client like this:
{conn, client} =
KindeClientSDK.init(
conn,
Application.get_env(:kinde_sdk, :domain),
Application.get_env(:kinde_sdk, :redirect_url),
Application.get_env(:kinde_sdk, :backend_client_id),
Application.get_env(:kinde_sdk, :client_secret),
:client_credentials,
Application.get_env(:kinde_sdk, :logout_redirect_url)
)
conn
will be phoenix connection here here. Now, you can use other implemented client functions,
like login
and get_token
.
ets-cache
ETS Cache
KindeClientSDK implements persistant ETS cache for storing the client data and authenticating variables.
You may call your created client like this:
client = KindeClientSDK.get_kinde_client(conn)
tokens
Tokens
We can use Kinde cache to get the tokens generated by login
and get_token
functions.
KindeClientSDK.get_all_data(conn)
Link to this section Summary
Functions
Returns whether if a user is logged in by verifying that the access token is still valid.
The function allows you to create organization. Similar to register, the returing conn
will redirect
to the your Kinde business registration page.
Perform a DELETE request.
Perform a DELETE request.
Perform a GET request.
Perform a GET request.
Returns all the Kinde data (tokens) returned.
Returns the authentication status.
Returns the Kinde cache PID from the conn
.
Returns a single claim from token and its value.
Returns token claims and their value.
Returns new grant type. Used by get_token
function.
Returns the Kinde client created from the conn
.
Returns the org code from the claims.
Given a permission value, returns if it is granted or not and relevant org code.
Returns an object with a list of permissions and also the relevant org code.
Fetches the tokens for your KindeClient. The tokens can be obtained through Kinde cache afterwards.
Returns the user details after successful authentication.
Returns the org code from the user token.
Perform a HEAD request.
Perform a HEAD request.
Used for initializing the Kinde client which will be then used other implemented client functions,
like login
and get_token
.
Login function for KindeClient. If grant type is :client_credentials
, then access token will be generated
and stored to KindeCache. For other grant types, returned conn
will redirect to the your Kinde business login page.
Log outs your client. Returned conn
redirects to you to Kinde logout page and
returns back to your logout redirect url.
Perform a OPTIONS request.
Perform a OPTIONS request.
Perform a PATCH request.
Perform a PATCH request.
Perform a POST request.
Perform a POST request.
Perform a PUT request.
Perform a PUT request.
Register function for your KindeClient. Returing conn
will redirect to the your Kinde business registration page.
Perform a request.
Perform request and raise in case of error.
Saves the Kinde client created into the conn
.
Perform a TRACE request.
Perform a TRACE request.
Link to this section Types
option()
@type option() :: {:method, Tesla.Env.method()} | {:url, Tesla.Env.url()} | {:query, Tesla.Env.query()} | {:headers, Tesla.Env.headers()} | {:body, Tesla.Env.body()} | {:opts, Tesla.Env.opts()}
Options that may be passed to a request function. See request/2
for detailed descriptions.
Link to this section Functions
authenticated?(conn)
@spec authenticated?(Plug.Conn.t()) :: boolean()
Returns whether if a user is logged in by verifying that the access token is still valid.
usage
Usage
KindeClientSDK.authenticated?(conn)
create_org(conn, client, additional_params \\ %{})
@spec create_org( Plug.Conn.t(), %KindeClientSDK{ additional_params: map(), auth_status: atom(), authorization_endpoint: <<_::64, _::_*8>>, cache_pid: pid(), client_id: any(), client_secret: any(), domain: binary(), grant_type: any(), logout_endpoint: <<_::56, _::_*8>>, logout_redirect_uri: any(), redirect_uri: binary(), scopes: any(), token_endpoint: <<_::64, _::_*8>> }, map() ) :: Plug.Conn.t()
The function allows you to create organization. Similar to register, the returing conn
will redirect
to the your Kinde business registration page.
usage
Usage
conn = KindeClientSDK.create_org(conn, client)
additional_params
is an optional and defaults to %{}
. It accepts :audience
, :org_code
and
:org_name
keys in the map with string as values.
delete(client, url, opts)
@spec delete(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.result()
Perform a DELETE request.
See request/1
or request/2
for options definition.
delete("/users")
delete("/users", query: [scope: "admin"])
delete(client, "/users")
delete(client, "/users", query: [scope: "admin"])
delete(client, "/users", body: %{name: "Jon"})
delete!(client, url, opts)
@spec delete!(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.t() | no_return()
Perform a DELETE request.
See request!/1
or request!/2
for options definition.
delete!("/users")
delete!("/users", query: [scope: "admin"])
delete!(client, "/users")
delete!(client, "/users", query: [scope: "admin"])
delete!(client, "/users", body: %{name: "Jon"})
get(client, url, opts)
@spec get(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.result()
Perform a GET request.
See request/1
or request/2
for options definition.
get("/users")
get("/users", query: [scope: "admin"])
get(client, "/users")
get(client, "/users", query: [scope: "admin"])
get(client, "/users", body: %{name: "Jon"})
get!(client, url, opts)
@spec get!(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.t() | no_return()
Perform a GET request.
See request!/1
or request!/2
for options definition.
get!("/users")
get!("/users", query: [scope: "admin"])
get!(client, "/users")
get!(client, "/users", query: [scope: "admin"])
get!(client, "/users", body: %{name: "Jon"})
get_all_data(conn)
@spec get_all_data(Plug.Conn.t()) :: %{ access_token: any(), expires_in: any(), id_token: any(), login_time_stamp: any(), token: any(), user: any(), oauth_code_verifier: any() }
Returns all the Kinde data (tokens) returned.
usage
Usage
data = KindeClientSDK.get_all_data(conn)
IO.inspect(data.access_token, label: "Access Token")
get_auth_status(conn)
@spec get_auth_status(Plug.Conn.t()) :: any()
Returns the authentication status.
usage
Usage
KindeClientSDK.get_auth_status(conn)
get_cache_pid(conn)
@spec get_cache_pid(Plug.Conn.t()) :: any()
Returns the Kinde cache PID from the conn
.
usage
Usage
pid = KindeClientSDK.get_cache_pid(conn)
get_claim(conn, key, token_type \\ :access_token)
@spec get_claim(Plug.Conn.t(), any(), any()) :: any()
Returns a single claim from token and its value.
usage
Usage
Third argument defaults to :access_token
KindeClientSDK.get_claim(conn, "jti")
If used with :id_token
KindeClientSDK.get_claim(conn, "jti", :id_token)
get_claims(conn, token_type \\ :access_token)
@spec get_claims(Plug.Conn.t(), any()) :: any()
Returns token claims and their value.
usage
Usage
Second argument defaults to :access_token
KindeClientSDK.get_claims(conn)
If used with :id_token
KindeClientSDK.get_claims(conn, :id_token)
get_grant_type(type)
@spec get_grant_type(
:authorization_code
| :authorization_code_flow_pkce
| :client_credentials
) ::
:authorization_code | :client_credentials
Returns new grant type. Used by get_token
function.
get_kinde_client(conn)
@spec get_kinde_client(Plug.Conn.t()) :: %KindeClientSDK{ additional_params: map(), auth_status: atom(), authorization_endpoint: <<_::64, _::_*8>>, cache_pid: pid(), client_id: any(), client_secret: any(), domain: binary(), grant_type: any(), logout_endpoint: <<_::56, _::_*8>>, logout_redirect_uri: any(), redirect_uri: binary(), scopes: any(), token_endpoint: <<_::64, _::_*8>> }
Returns the Kinde client created from the conn
.
usage
Usage
client = KindeClientSDK.get_kinde_client(conn)
get_organization(conn)
@spec get_organization(Plug.Conn.t()) :: %{org_code: any()}
Returns the org code from the claims.
usage
Usage
KindeClientSDK.get_user_organization(conn)
get_permission(conn, permission, token_type \\ :access_token)
@spec get_permission(Plug.Conn.t(), any(), any()) :: %{ is_granted: boolean(), org_code: any() }
Given a permission value, returns if it is granted or not and relevant org code.
usage
Usage
KindeClientSDK.get_permission(conn, "create:users")
KindeClientSDK.get_permission(conn, "create:users", :id_token)
get_permissions(conn, token_type \\ :access_token)
@spec get_permissions(Plug.Conn.t(), any()) :: %{org_code: any(), permissions: any()}
Returns an object with a list of permissions and also the relevant org code.
usage
Usage
KindeClientSDK.get_permissions(conn)
KindeClientSDK.get_permissions(conn, :id_token)
get_token(conn)
@spec get_token(Plug.Conn.t()) :: {Plug.Conn.t(), %KindeClientSDK{ additional_params: map(), auth_status: atom(), authorization_endpoint: <<_::64, _::_*8>>, cache_pid: pid(), client_id: any(), client_secret: any(), domain: binary(), grant_type: any(), logout_endpoint: <<_::56, _::_*8>>, logout_redirect_uri: any(), redirect_uri: binary(), scopes: any(), token_endpoint: <<_::64, _::_*8>> }}
Fetches the tokens for your KindeClient. The tokens can be obtained through Kinde cache afterwards.
usage
Usage
{conn, client} = KindeClientSDK.get_token(conn)
Get the tokens like this:
pid = Conn.get_session(conn, :kinde_cache_pid)
GenServer.call(pid, {:get_kinde_data, :kinde_access_token})
get_user_detail(conn)
@spec get_user_detail(Plug.Conn.t()) :: any()
Returns the user details after successful authentication.
usage
Usage
KindeClientSDK.get_user_detail(conn)
Returns nil
if not authenticated or if grant type is :client_credentials
.
get_user_organizations(conn)
@spec get_user_organizations(Plug.Conn.t()) :: %{org_codes: any()}
Returns the org code from the user token.
usage
Usage
KindeClientSDK.get_user_organizations(conn)
head(client, url, opts)
@spec head(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.result()
Perform a HEAD request.
See request/1
or request/2
for options definition.
head("/users")
head("/users", query: [scope: "admin"])
head(client, "/users")
head(client, "/users", query: [scope: "admin"])
head(client, "/users", body: %{name: "Jon"})
head!(client, url, opts)
@spec head!(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.t() | no_return()
Perform a HEAD request.
See request!/1
or request!/2
for options definition.
head!("/users")
head!("/users", query: [scope: "admin"])
head!(client, "/users")
head!(client, "/users", query: [scope: "admin"])
head!(client, "/users", body: %{name: "Jon"})
init(conn, domain, redirect_uri, client_id, client_secret, grant_type, logout_redirect_uri, scopes \\ "openid profile email offline", additional_params \\ %{})
@spec init( Plug.Conn.t(), binary(), binary(), any(), any(), any(), any(), binary(), map() ) :: {Plug.Conn.t(), %KindeClientSDK{ additional_params: map(), auth_status: :unauthenticated, authorization_endpoint: <<_::64, _::_*8>>, cache_pid: pid(), client_id: any(), client_secret: any(), domain: binary(), grant_type: any(), logout_endpoint: <<_::56, _::_*8>>, logout_redirect_uri: any(), redirect_uri: binary(), scopes: any(), token_endpoint: <<_::64, _::_*8>> }}
Used for initializing the Kinde client which will be then used other implemented client functions,
like login
and get_token
.
Initialize your client like this:
{conn, client} =
KindeClientSDK.init(
conn,
Application.get_env(:kinde_sdk, :domain),
Application.get_env(:kinde_sdk, :redirect_url),
Application.get_env(:kinde_sdk, :backend_client_id),
Application.get_env(:kinde_sdk, :client_secret),
:client_credentials,
Application.get_env(:kinde_sdk, :logout_redirect_url)
)
conn
will be phoenix connection here here.
scopes
is an optional and defaults to "openid profile email offline"
. Scopes can be defined as string.
additional_params
is an optional and defaults to %{}
. It accepts :audience
, :org_code
and
:org_name
keys in the map with string as values.
Throws for invalid domain
, redirect_uri
and additional_params
.
login(conn, client, additional_params \\ %{})
@spec login( Plug.Conn.t(), %KindeClientSDK{ additional_params: map(), auth_status: atom(), authorization_endpoint: <<_::64, _::_*8>>, cache_pid: pid(), client_id: any(), client_secret: any(), domain: binary(), grant_type: any(), logout_endpoint: <<_::56, _::_*8>>, logout_redirect_uri: any(), redirect_uri: binary(), scopes: any(), token_endpoint: <<_::64, _::_*8>> }, map() ) :: any()
Login function for KindeClient. If grant type is :client_credentials
, then access token will be generated
and stored to KindeCache. For other grant types, returned conn
will redirect to the your Kinde business login page.
Your callback function will call get_token
function to get the authenticated user's token.
usage
Usage
conn = KindeClientSDK.login(conn, client)
additional_params
is an optional and defaults to %{}
. It accepts :audience
, :org_code
and
:org_name
keys in the map with string as values.
Throws for invalid grant_type
.
logout(conn)
@spec logout(Plug.Conn.t()) :: Plug.Conn.t()
Log outs your client. Returned conn
redirects to you to Kinde logout page and
returns back to your logout redirect url.
usage
Usage
conn = KindeClientSDK.logout(conn)
options(client, url, opts)
@spec options(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.result()
Perform a OPTIONS request.
See request/1
or request/2
for options definition.
options("/users")
options("/users", query: [scope: "admin"])
options(client, "/users")
options(client, "/users", query: [scope: "admin"])
options(client, "/users", body: %{name: "Jon"})
options!(client, url, opts)
@spec options!(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.t() | no_return()
Perform a OPTIONS request.
See request!/1
or request!/2
for options definition.
options!("/users")
options!("/users", query: [scope: "admin"])
options!(client, "/users")
options!(client, "/users", query: [scope: "admin"])
options!(client, "/users", body: %{name: "Jon"})
patch(client, url, body, opts)
@spec patch(Tesla.Env.client(), Tesla.Env.url(), Tesla.Env.body(), [option()]) :: Tesla.Env.result()
Perform a PATCH request.
See request/1
or request/2
for options definition.
patch("/users", %{name: "Jon"})
patch("/users", %{name: "Jon"}, query: [scope: "admin"])
patch(client, "/users", %{name: "Jon"})
patch(client, "/users", %{name: "Jon"}, query: [scope: "admin"])
patch!(client, url, body, opts)
@spec patch!(Tesla.Env.client(), Tesla.Env.url(), Tesla.Env.body(), [option()]) :: Tesla.Env.t() | no_return()
Perform a PATCH request.
See request!/1
or request!/2
for options definition.
patch!("/users", %{name: "Jon"})
patch!("/users", %{name: "Jon"}, query: [scope: "admin"])
patch!(client, "/users", %{name: "Jon"})
patch!(client, "/users", %{name: "Jon"}, query: [scope: "admin"])
post(client, url, body, opts)
@spec post(Tesla.Env.client(), Tesla.Env.url(), Tesla.Env.body(), [option()]) :: Tesla.Env.result()
Perform a POST request.
See request/1
or request/2
for options definition.
post("/users", %{name: "Jon"})
post("/users", %{name: "Jon"}, query: [scope: "admin"])
post(client, "/users", %{name: "Jon"})
post(client, "/users", %{name: "Jon"}, query: [scope: "admin"])
post!(client, url, body, opts)
@spec post!(Tesla.Env.client(), Tesla.Env.url(), Tesla.Env.body(), [option()]) :: Tesla.Env.t() | no_return()
Perform a POST request.
See request!/1
or request!/2
for options definition.
post!("/users", %{name: "Jon"})
post!("/users", %{name: "Jon"}, query: [scope: "admin"])
post!(client, "/users", %{name: "Jon"})
post!(client, "/users", %{name: "Jon"}, query: [scope: "admin"])
put(client, url, body, opts)
@spec put(Tesla.Env.client(), Tesla.Env.url(), Tesla.Env.body(), [option()]) :: Tesla.Env.result()
Perform a PUT request.
See request/1
or request/2
for options definition.
put("/users", %{name: "Jon"})
put("/users", %{name: "Jon"}, query: [scope: "admin"])
put(client, "/users", %{name: "Jon"})
put(client, "/users", %{name: "Jon"}, query: [scope: "admin"])
put!(client, url, body, opts)
@spec put!(Tesla.Env.client(), Tesla.Env.url(), Tesla.Env.body(), [option()]) :: Tesla.Env.t() | no_return()
Perform a PUT request.
See request!/1
or request!/2
for options definition.
put!("/users", %{name: "Jon"})
put!("/users", %{name: "Jon"}, query: [scope: "admin"])
put!(client, "/users", %{name: "Jon"})
put!(client, "/users", %{name: "Jon"}, query: [scope: "admin"])
register(conn, client, additional_params \\ %{})
@spec register( Plug.Conn.t(), %KindeClientSDK{ additional_params: map(), auth_status: atom(), authorization_endpoint: <<_::64, _::_*8>>, cache_pid: pid(), client_id: any(), client_secret: any(), domain: binary(), grant_type: any(), logout_endpoint: <<_::56, _::_*8>>, logout_redirect_uri: any(), redirect_uri: binary(), scopes: any(), token_endpoint: <<_::64, _::_*8>> }, map() ) :: Plug.Conn.t()
Register function for your KindeClient. Returing conn
will redirect to the your Kinde business registration page.
usage
Usage
conn = KindeClientSDK.register(conn, client)
additional_params
is an optional and defaults to %{}
. It accepts :audience
, :org_code
and
:org_name
keys in the map with string as values.
request(client \\ %Tesla.Client{}, options)
@spec request(Tesla.Env.client(), [option()]) :: Tesla.Env.result()
Perform a request.
options
Options
:method
- the request method, one of [:head
,:get
,:delete
,:trace
,:options
,:post
,:put
,:patch
]:url
- either full url e.g. "http://example.com/some/path" or just "/some/path" if usingTesla.Middleware.BaseUrl
:query
- a keyword list of query params, e.g.[page: 1, per_page: 100]
:headers
- a keyworld list of headers, e.g.[{"content-type", "text/plain"}]
:body
- depends on used middleware:- by default it can be a binary
- if using e.g. JSON encoding middleware it can be a nested map
- if adapter supports it it can be a Stream with any of the above
:opts
- custom, per-request middleware or adapter options
examples
Examples
ExampleApi.request(method: :get, url: "/users/path")
# use shortcut methods
ExampleApi.get("/users/1")
ExampleApi.post(client, "/users", %{name: "Jon"})
request!(client \\ %Tesla.Client{}, options)
@spec request!(Tesla.Env.client(), [option()]) :: Tesla.Env.t() | no_return()
Perform request and raise in case of error.
This is similar to request/2
behaviour from Tesla 0.x
See request/2
for list of available options.
save_kinde_client(conn, client)
@spec save_kinde_client(Plug.Conn.t(), any()) :: :ok
Saves the Kinde client created into the conn
.
usage
Usage
KindeClientSDK.save_kinde_client(conn)
trace(client, url, opts)
@spec trace(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.result()
Perform a TRACE request.
See request/1
or request/2
for options definition.
trace("/users")
trace("/users", query: [scope: "admin"])
trace(client, "/users")
trace(client, "/users", query: [scope: "admin"])
trace(client, "/users", body: %{name: "Jon"})
trace!(client, url, opts)
@spec trace!(Tesla.Env.client(), Tesla.Env.url(), [option()]) :: Tesla.Env.t() | no_return()
Perform a TRACE request.
See request!/1
or request!/2
for options definition.
trace!("/users")
trace!("/users", query: [scope: "admin"])
trace!(client, "/users")
trace!(client, "/users", query: [scope: "admin"])
trace!(client, "/users", body: %{name: "Jon"})