An Elixir toolkit for the AT Protocol. hexdocs.pm/atex
elixir bluesky atproto decentralization
25
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(xrpc): add LoginClient moduledoc, fix auth_error? spec and handle_failure return type

+18 -5
+18 -5
lib/atex/xrpc/login_client.ex
··· 1 1 defmodule Atex.XRPC.LoginClient do 2 + @moduledoc """ 3 + Password/app-password based XRPC client for AT Protocol. 4 + 5 + Creates a session via `com.atproto.server.createSession` and handles automatic 6 + token refresh on 401 responses. For OAuth-based authentication, see 7 + `Atex.XRPC.OAuthClient`. 8 + 9 + ## Examples 10 + 11 + {:ok, client} = Atex.XRPC.LoginClient.login("https://bsky.social", "user.bsky.social", "password") 12 + {:ok, response, client} = Atex.XRPC.get(client, "app.bsky.actor.getProfile", params: [actor: "user.bsky.social"]) 13 + """ 14 + 2 15 alias Atex.XRPC 3 16 use TypedStruct 4 17 ··· 112 125 end 113 126 114 127 @spec handle_failure(t(), Req.Response.t(), Req.Request.t()) :: 115 - {:ok, Req.Response.t(), t()} | {:error, any()} 128 + {:ok, Req.Response.t(), t()} | {:error, any(), t()} 116 129 defp handle_failure(client, response, request) do 117 - if auth_error?(response.body) and client.refresh_token do 130 + if auth_error?(response) and client.refresh_token do 118 131 case refresh(client) do 119 132 {:ok, client} -> 120 133 case Req.request(put_auth(request, client.access_token)) do 121 134 {:ok, %{status: 200} = response} -> {:ok, response, client} 122 - {:ok, response} -> {:error, response} 135 + {:ok, response} -> {:error, response, client} 123 136 err -> err 124 137 end 125 138 ··· 127 140 err 128 141 end 129 142 else 130 - {:error, response} 143 + {:error, response, client} 131 144 end 132 145 end 133 146 ··· 135 148 defp validate_client(%__MODULE__{access_token: nil}), do: {:error, :no_token} 136 149 defp validate_client(%__MODULE__{} = client), do: {:ok, client} 137 150 138 - @spec auth_error?(body :: Req.Response.t()) :: boolean() 151 + @spec auth_error?(Req.Response.t()) :: boolean() 139 152 defp auth_error?(%{status: status}) when status in [401, 403], do: true 140 153 defp auth_error?(%{body: %{"error" => "InvalidToken"}}), do: true 141 154 defp auth_error?(_response), do: false