Class: AtProto::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/atproto_client/client.rb

Overview

The Client class handles authenticated HTTP requests to the AT Protocol services with DPoP token support and token request capabilities.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(private_key:, access_token: nil) ⇒ Client

Initializes a new AT Protocol client

Parameters:

  • private_key (OpenSSL::PKey::EC)

    The EC private key used for DPoP token signing (required)

  • access_token (String, nil) (defaults to: nil)

    Optional access token for authentication

Raises:

  • (ArgumentError)

    If private_key is not provided or not an OpenSSL::PKey::EC instance



17
18
19
20
21
# File 'lib/atproto_client/client.rb', line 17

def initialize(private_key:, access_token: nil)
  @private_key = private_key
  @access_token = access_token
  @dpop_handler = DpopHandler.new(private_key, access_token)
end

Instance Attribute Details

#access_tokenObject

Returns the value of attribute access_token.



9
10
11
# File 'lib/atproto_client/client.rb', line 9

def access_token
  @access_token
end

#dpop_handlerDpopHandler

The handler for DPoP token operations

Returns:



8
9
10
# File 'lib/atproto_client/client.rb', line 8

def dpop_handler
  @dpop_handler
end

Instance Method Details

#get_token!(code:, jwk:, client_id:, site:, endpoint:, redirect_uri:, code_verifier:) ⇒ Hash

Gets a new access token using an authorization code

Parameters:

  • code (String)

    The authorization code

  • jwk (Hash)

    The JWK for signing

  • client_id (String)

    The client ID

  • site (String)

    The token audience

  • endpoint (String)

    The token endpoint URL

  • redirect_uri (String)

    The application’s oauth callback url

Returns:

  • (Hash)

    The token response

Raises:

  • (AuthError)

    When forbidden by the server

  • (APIError)

    On other errors from the server



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/atproto_client/client.rb', line 65

def get_token!(code:, jwk:, client_id:, site:, endpoint:, redirect_uri:, code_verifier:)
  response = @dpop_handler.make_request(
    endpoint,
    :post,
    headers: {
      'Content-Type' => 'application/json',
      'Accept' => 'application/json'
    },
    body: token_params(
      code: code,
      jwk: jwk,
      client_id: client_id,
      site: site,
      redirect_uri: redirect_uri,
      code_verifier: code_verifier
    )
  )
  @access_token = response['access_token']
  response
end

#private_key=(private_key) ⇒ Object

Sets a new private key for DPoP token signing

Parameters:

  • private_key (OpenSSL::PKey::EC)

    The EC private key to use for signing DPoP tokens (required)

Raises:

  • (ArgumentError)

    If private_key is not an OpenSSL::PKey::EC instance



27
28
29
# File 'lib/atproto_client/client.rb', line 27

def private_key=(private_key)
  @dpop_handler = @dpop_handler.new(private_key, @access_token)
end

#refresh_token!(refresh_token:, jwk:, client_id:, site:, endpoint:) ⇒ Hash

Refreshes the access token using a refresh token

Parameters:

  • refresh_token (String)

    The refresh token

  • jwk (Hash)

    The JWK for signing

  • client_id (String)

    The client ID

  • site (String)

    The token audience

  • endpoint (String)

    The token endpoint URL

Returns:

  • (Hash)

    The token response

Raises:

  • (AuthError)

    When forbidden by the server

  • (APIError)

    On other errors from the server



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/atproto_client/client.rb', line 97

def refresh_token!(refresh_token:, jwk:, client_id:, site:, endpoint:)
  @dpop_handler.access_token = nil
  response = @dpop_handler.make_request(
    endpoint,
    :post,
    headers: {
      'Content-Type' => 'application/json',
      'Accept' => 'application/json'
    },
    body: refresh_token_params(
      refresh_token: refresh_token,
      jwk: jwk,
      client_id: client_id,
      site: site
    )
  )
  @access_token = response['access_token']
  @dpop_handler.access_token = @access_token
  response
end

#request(method, url, params: {}, body: nil, headers: {}) ⇒ Hash

Makes an authenticated HTTP request

Parameters:

  • method (Symbol)

    The HTTP method to use (:get, :post, etc.)

  • url (String)

    The URL to send the request to

  • params (Hash) (defaults to: {})

    Optional query parameters to be added to the URL

  • body (Hash, nil) (defaults to: nil)

    Optional request body for POST/PUT requests

Returns:

  • (Hash)

    The parsed JSON response

Raises:



42
43
44
45
46
47
48
49
50
51
# File 'lib/atproto_client/client.rb', line 42

def request(method, url, params: {}, body: nil, headers: {})
  uri = URI(url)
  uri.query = URI.encode_www_form(params) if params.any?
  @dpop_handler.make_request(
    uri.to_s,
    method,
    headers: { 'Authorization' => "DPoP #{@access_token}" }.merge(headers),
    body: body
  )
end