class CivicSIPSdk::Client

Constants

AUTH_CODE_PATH
BASE_URL
ENV_VAR
HTTP_REQUEST_METHOD
MIMETYPE_JSON
PUBLIC_HEX
TEST_ENV

Public Class Methods

new(config:) click to toggle source

Creates a client

@param config [CivicSIPSdk::AppConfig] app_config that sets all the parameters of the client

# File lib/civic_sip_sdk/client.rb, line 24
def initialize(config:)
  @config = config
  @test_env = ENV[ENV_VAR] == TEST_ENV
end

Public Instance Methods

exchange_code(jwt_token:) click to toggle source

Exchange authorization code in the form of a JWT Token for the user data requested in the scope request.

@param jwt_token [String] a JWT token that contains the authorization code @return [CivicSIPSdk::UserData] user data returned from SIP

# File lib/civic_sip_sdk/client.rb, line 34
def exchange_code(jwt_token:)
  json_body_str = JSON.generate('authToken' => jwt_token)

  response = HTTParty.post(
    "#{BASE_URL}/#{@config.env}/#{AUTH_CODE_PATH}",
    headers: {
      'Content-Type' => MIMETYPE_JSON,
      'Accept' => MIMETYPE_JSON,
      'Content-Length' => json_body_str.size.to_s,
      'Authorization' => authorization_header(body: json_body_str)
    },
    body: json_body_str
  )

  unless response.code == 200
    raise StandardError.new(
      "Failed to exchange JWT token. HTTP status: #{response.code}, response body: #{response.body}"
    )
  end

  res_payload = JSON.parse(response.body)
  extract_user_data(response: res_payload)
end

Private Instance Methods

authorization_header(body:) click to toggle source
# File lib/civic_sip_sdk/client.rb, line 60
def authorization_header(body:)
  jwt_token = Crypto.jwt_token(
    app_id: @config.id,
    sip_base_url: BASE_URL,
    data: {
      method: HTTP_REQUEST_METHOD,
      path: AUTH_CODE_PATH
    },
    private_key: @config.private_key
  )

  civic_extension = Crypto.civic_extension(secret: @config.secret, body: body)

  "Civic #{jwt_token}.#{civic_extension}"
end
extract_user_data(response:) click to toggle source
# File lib/civic_sip_sdk/client.rb, line 76
def extract_user_data(response:)
  # only verify the token if it's in production (test is using an expired token)
  decoded_token = Crypto.decode_jwt_token(
    token: response['data'],
    public_hex_key: PUBLIC_HEX,
    should_verify: !@test_env
  )
  data_text = if response['encrypted']
                # decrypt the data attr
                Crypto.decrypt(
                  text: decoded_token['data'],
                  secret: @config.secret
                )
              else
                decoded_data['data']
              end

  UserData.new(
    user_id: response['userId'],
    data_items: JSON.parse(data_text)
  )
end