Atex.XRPC.OAuthClient
(atex v0.9.1)
View Source
OAuth client for making authenticated XRPC requests to AT Protocol servers.
The client holds a composite session key ("<did>:<nonce>") and talks to
Atex.OAuth.SessionStore to retrieve sessions internally to make requests.
It only works for users that have completed an OAuth flow; see
Atex.OAuth.Plug for an existing method of doing that.
The entire OAuth session lifecycle is handled transparently, with the access token being refreshed automatically as required.
Usage
# Create from an existing composite session key
{:ok, client} = Atex.XRPC.OAuthClient.new("did:plc:abc123:device-nonce")
# Or extract from a Plug.Conn after OAuth flow
{:ok, client} = Atex.XRPC.OAuthClient.from_conn(conn)
# Retrieve just the DID from a client
"did:plc:abc123" = Atex.XRPC.OAuthClient.did(client)
# Make XRPC requests
{:ok, response, client} = Atex.XRPC.get(client, "com.atproto.repo.listRecords")
Summary
Functions
Returns the DID portion of the client's composite session key.
Create an OAuthClient from a Plug.Conn.
Make a GET request to an XRPC endpoint.
Create a new OAuthClient from a composite session key ("<did>:<nonce>").
Make a POST request to an XRPC endpoint.
Ask the client's OAuth server for a new set of auth tokens.
Types
@type t() :: %Atex.XRPC.OAuthClient{session_key: String.t()}
Functions
Returns the DID portion of the client's composite session key.
The session key has the form "<did>:<nonce>". This function extracts and
returns everything up to the final : separator, which is the user's DID.
Examples
iex> client = %Atex.XRPC.OAuthClient{session_key: "did:plc:abc123:mynonce"}
iex> Atex.XRPC.OAuthClient.did(client)
"did:plc:abc123"
@spec from_conn(Plug.Conn.t()) :: {:ok, t()} | :error | {:error, atom()}
Create an OAuthClient from a Plug.Conn.
Reads the active session key from conn.session (stored under
:atex_active_session) and validates that the OAuth session is still valid.
If the token is expired or expiring soon, it attempts to refresh it.
Requires the conn to have passed through Plug.Session and
Plug.Conn.fetch_session/2.
Returns
{:ok, client}- Successfully created client{:error, :reauth}- Session exists but refresh failed; user needs to re-authenticate:error- No active session found in conn
Examples
# After OAuth flow completes
{:ok, client} = Atex.XRPC.OAuthClient.from_conn(conn)
Make a GET request to an XRPC endpoint.
See Atex.XRPC.get/3 for details.
Create a new OAuthClient from a composite session key ("<did>:<nonce>").
Validates that an OAuth session exists for the given key in the session store before returning the client struct.
Examples
iex> Atex.XRPC.OAuthClient.new("did:plc:abc123:mynonce")
{:ok, %Atex.XRPC.OAuthClient{session_key: "did:plc:abc123:mynonce"}}
iex> Atex.XRPC.OAuthClient.new("did:plc:nosession:nonce")
{:error, :not_found}
Make a POST request to an XRPC endpoint.
See Atex.XRPC.post/3 for details.
@spec refresh(client :: t()) :: {:ok, Atex.OAuth.Session.t()} | {:error, any()}
Ask the client's OAuth server for a new set of auth tokens.
Fetches the session, refreshes the tokens, creates a new session with the updated tokens, stores it, and returns the new session.
You shouldn't need to call this manually for the most part, the client does its best to refresh automatically when it needs to.
This function acquires a lock on the session to prevent concurrent refresh attempts.