Liking cljdoc? Tell your friends :D

dk.simongray.indieauth

IndieAuth for clients: the identifiers of users, clients and servers, the discovery of a user's server, and signing in with it.

The code follows the IndieAuth Living Standard of 11 July 2024 at https://indieauth.spec.indieweb.org/ and cites its sections. The server is in dk.simongray.indieauth.server, the checks of a resource server in dk.simongray.indieauth.resource, the signed maps that carry a value through a browser in dk.simongray.indieauth.signed, and the signed state of a sign-in, which other protocols can use too, in dk.simongray.indieauth.state. The other namespaces are internal and named for what they hold, e.g. identifier for the rules of identifiers and grant for the codes and tokens of a server.

IndieAuth for clients: the identifiers of users, clients and servers,
the discovery of a user's server, and signing in with it.

The code follows the IndieAuth Living Standard of 11 July 2024 at
https://indieauth.spec.indieweb.org/ and cites its sections. The server
is in dk.simongray.indieauth.server, the checks of a resource server in
dk.simongray.indieauth.resource, the signed maps that carry a value
through a browser in dk.simongray.indieauth.signed, and the signed state
of a sign-in, which other protocols can use too, in
dk.simongray.indieauth.state. The other namespaces are internal and
named for what they hold, e.g. identifier for the rules of identifiers
and grant for the codes and tokens of a server.
raw docstring

authorization-requestclj/s

(authorization-request
  {:keys [me authorization-endpoint token-endpoint] :as discovery}
  {:keys [client-id redirect-uri scope secret data] :as opts})

The URL at the authorization endpoint of the discovery to send the user's browser to, and the session to keep until the browser comes back, as a map of :url and :session, by opts:

  • :client-id, the client identifier
  • :redirect-uri, the URL that the browser comes back to
  • :scope, the scopes to ask for, as a text or a collection. Without one, the answer has the user's profile URL alone.
  • :secret, a text of 32 bytes or more, e.g. a token, that signs the session into a cookie for state-session
  • :data, any EDN that the session carries for you
  • :now-fn and :max-cookie-bytes, as default-options has them

Keep the session for the browser's return, e.g. in a session store, or with a :secret, only its :cookie, in an HttpOnly cookie. A scope that asks for an access token needs a token endpoint, and a server without one gives a map of the :error.

The URL at the authorization endpoint of the `discovery` to send the
user's browser to, and the session to keep until the browser comes
back, as a map of :url and :session, by `opts`:

- :client-id, the client identifier
- :redirect-uri, the URL that the browser comes back to
- :scope, the scopes to ask for, as a text or a collection. Without one,
  the answer has the user's profile URL alone.
- :secret, a text of 32 bytes or more, e.g. a token, that signs the
  session into a cookie for state-session
- :data, any EDN that the session carries for you
- :now-fn and :max-cookie-bytes, as default-options has them

Keep the session for the browser's return, e.g. in a session store, or
with a :secret, only its :cookie, in an HttpOnly cookie. A scope that
asks for an access token needs a token endpoint, and a server without
one gives a map of the :error.
sourceraw docstring

callback-problemclj/s

(callback-problem {:keys [state issuer] :as session} params)

What's wrong with the query params that the browser came back with, for the session, as a map of the :type and the :reason, or nil.

The params are a map with texts or keywords as keys. An error from the server, e.g. access_denied when the user said no, is a problem of the type ::authorization-error, with the server's :code.

What's wrong with the query `params` that the browser came back with,
for the `session`, as a map of the :type and the :reason, or nil.

The params are a map with texts or keywords as keys. An error from the
server, e.g. access_denied when the user said no, is a problem of the
type ::authorization-error, with the server's :code.
sourceraw docstring

canonical-urlclj/s

(canonical-url s)

The URL that the text s names, in the canonical form that IndieAuth compares, or nil when it names no http or https URL.

A host alone becomes an https URL, as people write it in a sign-in form. The scheme and the host are in lower case, a default port is left out, and an empty path is /. Nothing else changes, so the result can be a URL that isn't a valid profile URL.

(canonical-url "Example.com") ;; => "https://example.com/"
The URL that the text `s` names, in the canonical form that IndieAuth
compares, or nil when it names no http or https URL.

A host alone becomes an https URL, as people write it in a sign-in
form. The scheme and the host are in lower case, a default port is left
out, and an empty path is /. Nothing else changes, so the result can be
a URL that isn't a valid profile URL.

    (canonical-url "Example.com") ;; => "https://example.com/"
sourceraw docstring

client-id?clj/s

(client-id? s)

Whether s is a valid client identifier: an http or https URL with a domain name, 127.0.0.1 or [::1], without a fragment, a user name or a password, or a . or .. segment in its path. Unlike a profile URL, it can have a port.

Whether `s` is a valid client identifier: an http or https URL with a
domain name, 127.0.0.1 or [::1], without a fragment, a user name or a
password, or a . or .. segment in its path. Unlike a profile URL, it
can have a port.
sourceraw docstring

client-metadataclj/s

(client-metadata
  {:keys [client-id client-name client-uri logo-uri redirect-uris] :as opts})

The client metadata document to serve at the client identifier, as a map of its JSON, by opts:

  • :client-id, the client identifier
  • :client-name, the name of the client to show the user
  • :client-uri, a page about the client, which is a prefix of the client identifier, and the client identifier by default
  • :logo-uri, the URL of its logo
  • :redirect-uris, the redirect URLs, which must list any on another host than the client identifier's
The client metadata document to serve at the client identifier, as a
map of its JSON, by `opts`:

- :client-id, the client identifier
- :client-name, the name of the client to show the user
- :client-uri, a page about the client, which is a prefix of the client
  identifier, and the client identifier by default
- :logo-uri, the URL of its logo
- :redirect-uris, the redirect URLs, which must list any on another
  host than the client identifier's
sourceraw docstring

client-metadata-handlerclj/s

(client-metadata-handler opts)

A Ring handler that serves the client metadata document of the opts of client-metadata as JSON, which a page in any browser can read.

A Ring handler that serves the client metadata document of the `opts`
of client-metadata as JSON, which a page in any browser can read.
sourceraw docstring

code-challengeclj/s

(code-challenge verifier)

The S256 code challenge of the code verifier: its SHA-256 in the URL-safe letters of base64.

The S256 code challenge of the code `verifier`: its SHA-256 in the
URL-safe letters of base64.
sourceraw docstring

code-verifierclj/s

(code-verifier)

A new PKCE code verifier: 43 random characters of the URL-safe letters of base64, from 32 random bytes.

A new PKCE code verifier: 43 random characters of the URL-safe letters
of base64, from 32 random bytes.
sourceraw docstring

code-verifier?clj/s

(code-verifier? s)

Whether s is a PKCE code verifier: 43 to 128 of the characters A-Z, a-z, 0-9, -, ., _ and ~.

Whether `s` is a PKCE code verifier: 43 to 128 of the characters A-Z,
a-z, 0-9, -, ., _ and ~.
sourceraw docstring

confirm!clj/s

(confirm! {:keys [urls authorization-endpoint] :as session} me opts)

Confirm that the profile URL me, which the server of the session gave, names that server, with opts, and give a map of the :me, or of the :error. In ClojureScript, it gives a promise.

It does when me is the URL that the user gave, or one that discovery went through, and else when the page of me names the same authorization endpoint.

Confirm that the profile URL `me`, which the server of the `session`
gave, names that server, with `opts`, and give a map of the :me, or of
the :error. In ClojureScript, it gives a promise.

It does when `me` is the URL that the user gave, or one that discovery
went through, and else when the page of `me` names the same
authorization endpoint.
sourceraw docstring

default-optionsclj/s

The default of each option of a client that has one, which follows IndieAuth:

  • :profile-url-pred, profile-url?, the URLs that a user can sign in as
  • :body-links?, false: only the head of a page names its server, since anyone who writes in its body could name another
  • :session-seconds, how long a user has to sign in at the server
  • :max-cookie-bytes, state/max-cookie-bytes: the largest cookie of a signed session, past which authorization-request throws
  • :max-redirects, how many redirects discovery follows
  • :timeout-seconds, :max-page-bytes and :max-json-bytes, the limits of each request
  • :send, http/send-public!, which sends to the public internet alone
  • :now-fn, a function that gives the instant now
The default of each option of a client that has one, which follows
IndieAuth:

- :profile-url-pred, profile-url?, the URLs that a user can sign in as
- :body-links?, false: only the head of a page names its server, since
  anyone who writes in its body could name another
- :session-seconds, how long a user has to sign in at the server
- :max-cookie-bytes, state/max-cookie-bytes: the largest cookie of a
  signed session, past which authorization-request throws
- :max-redirects, how many redirects discovery follows
- :timeout-seconds, :max-page-bytes and :max-json-bytes, the limits of
  each request
- :send, http/send-public!, which sends to the public internet alone
- :now-fn, a function that gives the instant now
sourceraw docstring

discover!clj/s

(discover! url)
(discover! url opts)

Fetch the page of the profile URL url and the metadata of the server that it names, with opts, and give the server as a map:

  • :me, the URL in canonical form
  • :urls, the URLs that discovery went through, from :me to the last redirect
  • :metadata-url and :metadata, unless the page has only older links
  • :issuer and the endpoints that the server has

A failure gives a map of the :error, with its :type and :reason. The opts are those of default-options and http/fetch!. In ClojureScript, it gives a promise.

Fetch the page of the profile URL `url` and the metadata of the server
that it names, with `opts`, and give the server as a map:

- :me, the URL in canonical form
- :urls, the URLs that discovery went through, from :me to the last
  redirect
- :metadata-url and :metadata, unless the page has only older links
- :issuer and the endpoints that the server has

A failure gives a map of the :error, with its :type and :reason. The
`opts` are those of default-options and http/fetch!. In ClojureScript,
it gives a promise.
sourceraw docstring

endpointsclj/s

(endpoints response)
(endpoints response opts)

The URL of the metadata that the response of a profile URL names, as a map of :metadata-url, or else the endpoints of its older links, as a map of :authorization-endpoint and :token-endpoint, by the :body-links? of opts. Nil when it names none.

The Link headers count before the page, and a page counts when it's HTML. A relative URL counts from the URL of the response, or from the base of the page.

The URL of the metadata that the `response` of a profile URL names, as
a map of :metadata-url, or else the endpoints of its older links, as a
map of :authorization-endpoint and :token-endpoint, by the :body-links?
of `opts`. Nil when it names none.

The Link headers count before the page, and a page counts when it's
HTML. A relative URL counts from the URL of the response, or from the
base of the page.
sourceraw docstring

issuer-of?clj/s

(issuer-of? issuer metadata-url)

Whether the issuer identifier fits the URL of its metadata, metadata-url: a prefix of it that ends where a path segment ends, or the issuer whose well-known metadata it is.

Whether the `issuer` identifier fits the URL of its metadata,
`metadata-url`: a prefix of it that ends where a path segment ends, or
the issuer whose well-known metadata it is.
sourceraw docstring

issuer?clj/s

(issuer? s)

Whether s is a valid issuer identifier of a server: an https URL with a host, and without a query or a fragment.

Whether `s` is a valid issuer identifier of a server: an https URL with
a host, and without a query or a fragment.
sourceraw docstring

metadata-problemclj/s

(metadata-problem {:keys [issuer authorization_endpoint token_endpoint]
                   :as metadata}
                  metadata-url)

What's wrong with the metadata of a server, the map of its JSON, from metadata-url, or nil.

What's wrong with the `metadata` of a server, the map of its JSON, from
`metadata-url`, or nil.
sourceraw docstring

profile-scopesclj/s

The scopes that ask for the user's profile information rather than for an access token: profile, and email, which comes with profile alone.

The scopes that ask for the user's profile information rather than for
an access token: profile, and email, which comes with profile alone.
sourceraw docstring

profile-url?clj/s

(profile-url? s)

Whether s is a valid profile URL of a user: an http or https URL with a domain name, without a port, a fragment, a user name or a password, or a . or .. segment in its path.

(profile-url? "https://example.com/users?id=100") ;; => true
(profile-url? "https://example.com:8443/")        ;; => false
Whether `s` is a valid profile URL of a user: an http or https URL with
a domain name, without a port, a fragment, a user name or a password,
or a . or .. segment in its path.

    (profile-url? "https://example.com/users?id=100") ;; => true
    (profile-url? "https://example.com:8443/")        ;; => false
sourceraw docstring

redeem!clj/s

(redeem! session params)
(redeem! session params opts)

Finish signing in when the user's browser comes back with the query params, for the session that authorization-request gave, with opts, and give what the server answered: the map of its JSON, e.g. with :me, :access_token, :scope and :profile, with the :me in canonical form. In ClojureScript, it gives a promise.

It checks the params with callback-problem, redeems the code with redemption-request, and confirms the :me with confirm!. A failure gives a map of the :error, with its :type and :reason. Only the :me says who the user is, never the :profile. The opts are those of default-options.

Finish signing in when the user's browser comes back with the query
`params`, for the `session` that authorization-request gave, with
`opts`, and give what the server answered: the map of its JSON, e.g.
with :me, :access_token, :scope and :profile, with the :me in canonical
form. In ClojureScript, it gives a promise.

It checks the params with callback-problem, redeems the code with
redemption-request, and confirms the :me with confirm!. A failure gives
a map of the :error, with its :type and :reason. Only the :me says who
the user is, never the :profile. The `opts` are those of
default-options.
sourceraw docstring

redemptionclj/s

(redemption response)
(redemption {:keys [status body] :as response} opts)

The answer in the response to a redemption-request, by the :profile-url-pred of opts: the map of its JSON, with the :me in canonical form, or a map of the :error.

An error of the server is of the type ::redemption-error, with the :code that the server gave, e.g. invalid_grant. An answer without a valid profile URL as its me is an error too.

The answer in the `response` to a redemption-request, by the
:profile-url-pred of `opts`: the map of its JSON, with the :me in
canonical form, or a map of the :error.

An error of the server is of the type ::redemption-error, with the :code
that the server gave, e.g. invalid_grant. An answer without a valid
profile URL as its me is an error too.
sourceraw docstring

redemption-requestclj/s

(redemption-request {:keys [scope client-id redirect-uri code-verifier]
                     :as session}
                    code)

The request map that redeems the code for the session: at the token endpoint for an access token, when the session asks for one, and else at the authorization endpoint for the profile URL alone. The body is a hidden text of wary-fetch, since it holds the code and the verifier.

The request map that redeems the `code` for the `session`: at the token
endpoint for an access token, when the session asks for one, and else
at the authorization endpoint for the profile URL alone. The body is a
hidden text of wary-fetch, since it holds the code and the verifier.
sourceraw docstring

refresh!clj/s

(refresh! session refresh-token)
(refresh! session refresh-token opts)

Exchange the refresh-token for a new access token at the token endpoint of the session, with opts, and give the answer as redeem! does. In ClojureScript, it gives a promise.

The answer has a new :refresh_token when the server gives one, which replaces the old one, as section 5.5.1 says. The opts are those of refresh-request and default-options.

Exchange the `refresh-token` for a new access token at the token
endpoint of the `session`, with `opts`, and give the answer as redeem!
does. In ClojureScript, it gives a promise.

The answer has a new :refresh_token when the server gives one, which
replaces the old one, as section 5.5.1 says. The `opts` are those of
refresh-request and default-options.
sourceraw docstring

refresh-requestclj/s

(refresh-request session refresh-token)
(refresh-request {:keys [token-endpoint client-id] :as session}
                 refresh-token
                 {:keys [scope] :as opts})

The request map that exchanges the refresh-token for a new access token at the token endpoint of the session, for the :scope of opts, the scopes of the session by default.

A scope that the session didn't ask for throws, since a refresh asks for the same scopes or fewer.

The request map that exchanges the `refresh-token` for a new access
token at the token endpoint of the `session`, for the :scope of `opts`,
the scopes of the session by default.

A scope that the session didn't ask for throws, since a refresh asks for
the same scopes or fewer.
sourceraw docstring

revocation-requestclj/s

(revocation-request {:keys [revocation-endpoint token-endpoint] :as session}
                    token)

The request map that revokes the token, an access token or a refresh token, at the revocation endpoint of the session. Without one, it goes to the token endpoint with action=revoke, as earlier versions of IndieAuth had it.

The request map that revokes the `token`, an access token or a refresh
token, at the revocation endpoint of the `session`. Without one, it goes
to the token endpoint with action=revoke, as earlier versions of
IndieAuth had it.
sourceraw docstring

revoke!clj/s

(revoke! session token)
(revoke! {:keys [revocation-endpoint token-endpoint] :as session} token opts)

Revoke the token, an access token or a refresh token, at the server of the session, with opts, e.g. when the user signs out, and give a map of the :status, or of the :error. In ClojureScript, it gives a promise.

A server revokes a refresh token with the access tokens of its grant. The opts are those of default-options.

Revoke the `token`, an access token or a refresh token, at the server of
the `session`, with `opts`, e.g. when the user signs out, and give a map
of the :status, or of the :error. In ClojureScript, it gives a promise.

A server revokes a refresh token with the access tokens of its grant.
The `opts` are those of default-options.
sourceraw docstring

scope-textclj/s

(scope-text scopes)

The scopes, a collection of texts, as the text of a scope parameter, or nil for none.

The `scopes`, a collection of texts, as the text of a scope parameter,
or nil for none.
sourceraw docstring

scopesclj/s

(scopes x)

The scopes of x, a text of scopes separated by spaces, or a collection of them, as a vector without repeats. It's empty when there are none, and nil when a scope has a character that a scope can't have.

The scopes of `x`, a text of scopes separated by spaces, or a collection
of them, as a vector without repeats. It's empty when there are none, and
nil when a scope has a character that a scope can't have.
sourceraw docstring

state-sessionclj/s

(state-session secret state cookie)
(state-session secret state cookie opts)

The session that the signed cookie carries, which authorization-request gave with the secret, if its state is the state that came back, or nil. It's nil too when the cookie is older than the :session-seconds of opts.

The cookie comes from the browser that came back, so that only the browser that started the sign-in can finish it.

The session that the signed `cookie` carries, which authorization-request
gave with the `secret`, if its state is the `state` that came back, or
nil. It's nil too when the cookie is older than the :session-seconds of
`opts`.

The cookie comes from the browser that came back, so that only the
browser that started the sign-in can finish it.
sourceraw docstring

tokenclj/s

(token)
(token n)

A random text of n bytes, 32 by default, that nobody can guess, e.g. for a state, a secret or an access token. The bytes come from a secure source, and the text is in the URL-safe letters of base64.

A random text of `n` bytes, 32 by default, that nobody can guess, e.g.
for a state, a secret or an access token. The bytes come from a secure
source, and the text is in the URL-safe letters of base64.
sourceraw docstring

token-scope?clj/s

(token-scope? scopes)

Whether the scopes ask for an access token: whether one of them asks for more than profile information.

Whether the `scopes` ask for an access token: whether one of them asks
for more than profile information.
sourceraw docstring

userinfo!clj/s

(userinfo! session access-token)
(userinfo! {:keys [userinfo-endpoint] :as session} access-token opts)

Fetch the user's profile information from the userinfo endpoint of the session with the access-token, which needs the profile scope, with opts, and give the map of its JSON, or of the :error. In ClojureScript, it gives a promise.

Like the :profile of redeem!, it never says who the user is. The opts are those of default-options.

Fetch the user's profile information from the userinfo endpoint of the
`session` with the `access-token`, which needs the profile scope, with
`opts`, and give the map of its JSON, or of the :error. In ClojureScript,
it gives a promise.

Like the :profile of redeem!, it never says who the user is. The `opts`
are those of default-options.
sourceraw docstring

well-known-urlclj/s

(well-known-url issuer)

The URL of the metadata of the server whose issuer identifier is issuer, at the well-known location of RFC 8414.

(well-known-url "https://example.com/indieauth/")
;; => "https://example.com/.well-known/oauth-authorization-server/indieauth"
The URL of the metadata of the server whose issuer identifier is
`issuer`, at the well-known location of RFC 8414.

    (well-known-url "https://example.com/indieauth/")
    ;; => "https://example.com/.well-known/oauth-authorization-server/indieauth"
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close