class Spaceship::ConnectAPI::Token

Constants

DEFAULT_TOKEN_DURATION
MAX_TOKEN_DURATION

maximum expiration supported by AppStore (20 minutes)

Attributes

duration[R]
expiration[R]
in_house[RW]

Temporary attribute not needed to create the JWT text There is no way to determine if the team associated with this key is for App Store or Enterprise so this is the temporary workaround

issuer_id[R]
key_id[R]
key_raw[R]
text[R]

Public Class Methods

create(key_id: nil, issuer_id: nil, filepath: nil, key: nil, is_key_content_base64: false, duration: nil, in_house: nil, **) click to toggle source
# File spaceship/lib/spaceship/connect_api/token.rb, line 52
def self.create(key_id: nil, issuer_id: nil, filepath: nil, key: nil, is_key_content_base64: false, duration: nil, in_house: nil, **)
  key_id ||= ENV['SPACESHIP_CONNECT_API_KEY_ID']
  issuer_id ||= ENV['SPACESHIP_CONNECT_API_ISSUER_ID']
  filepath ||= ENV['SPACESHIP_CONNECT_API_KEY_FILEPATH']
  duration ||= ENV['SPACESHIP_CONNECT_API_TOKEN_DURATION']

  in_house_env = ENV['SPACESHIP_CONNECT_API_IN_HOUSE']
  in_house ||= !["", "no", "false", "off", "0"].include?(in_house_env) if in_house_env

  key ||= ENV['SPACESHIP_CONNECT_API_KEY']
  key ||= File.binread(filepath)

  if !key.nil? && is_key_content_base64
    key = Base64.decode64(key)
  end

  self.new(
    key_id: key_id,
    issuer_id: issuer_id,
    key: OpenSSL::PKey::EC.new(key),
    key_raw: key,
    duration: duration,
    in_house: in_house
  )
end
from(hash: nil, filepath: nil) click to toggle source
# File spaceship/lib/spaceship/connect_api/token.rb, line 31
def self.from(hash: nil, filepath: nil)
  api_token ||= self.create(**hash.transform_keys(&:to_sym)) if hash
  api_token ||= self.from_json_file(filepath) if filepath
  return api_token
end
from_json_file(filepath) click to toggle source
# File spaceship/lib/spaceship/connect_api/token.rb, line 37
def self.from_json_file(filepath)
  json = JSON.parse(File.read(filepath), { symbolize_names: true })

  missing_keys = []
  missing_keys << 'key_id' unless json.key?(:key_id)
  missing_keys << 'issuer_id' unless json.key?(:issuer_id)
  missing_keys << 'key' unless json.key?(:key)

  unless missing_keys.empty?
    raise "App Store Connect API key JSON is missing field(s): #{missing_keys.join(', ')}"
  end

  self.create(**json)
end
new(key_id: nil, issuer_id: nil, key: nil, key_raw: nil, duration: nil, in_house: nil) click to toggle source
# File spaceship/lib/spaceship/connect_api/token.rb, line 78
def initialize(key_id: nil, issuer_id: nil, key: nil, key_raw: nil, duration: nil, in_house: nil)
  @key_id = key_id
  @key = key
  @key_raw = key_raw
  @issuer_id = issuer_id
  @duration = duration
  @in_house = in_house

  @duration ||= DEFAULT_TOKEN_DURATION
  @duration = @duration.to_i if @duration

  refresh!
end

Public Instance Methods

expired?() click to toggle source
# File spaceship/lib/spaceship/connect_api/token.rb, line 108
def expired?
  @expiration < Time.now
end
refresh!() click to toggle source
# File spaceship/lib/spaceship/connect_api/token.rb, line 92
def refresh!
  @expiration = Time.now + @duration

  header = {
    kid: key_id
  }

  payload = {
    iss: issuer_id,
    exp: @expiration.to_i,
    aud: 'appstoreconnect-v1'
  }

  @text = JWT.encode(payload, @key, 'ES256', header)
end
write_key_to_file(path) click to toggle source
# File spaceship/lib/spaceship/connect_api/token.rb, line 112
def write_key_to_file(path)
  File.open(path, 'w') { |f| f.write(@key_raw) }
end