itunes_receipt_decoder 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/itunes_receipt_decoder/decode/base.rb +2 -7
- data/lib/itunes_receipt_decoder/decode/transaction_receipt.rb +27 -23
- data/lib/itunes_receipt_decoder/decode/unified_receipt.rb +12 -17
- data/lib/itunes_receipt_decoder/version.rb +1 -1
- data/lib/itunes_receipt_decoder.rb +5 -1
- metadata +11 -12
- data/lib/itunes_receipt_decoder/config.rb +0 -29
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 15142fd0c14f72948823cfb09e134b9e85bc835a
         | 
| 4 | 
            +
              data.tar.gz: 9cf2d1412ca0c789d8fe7193aacee887c2cb0272
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a25dadcf77df2605adf9c2c403df7a214c425ad2f4623fc7aeef96bb11689fb542e40d96c30b82a73c47cd1bc0afd4b236d680f1316971f5d9e1aef3703b78cb
         | 
| 7 | 
            +
              data.tar.gz: f63a1df3a9733142c4caf9eec3685b7b5ee479f4414f66af3b152c53d9638368c57ae76679ace8873c87ca828286a2f4fc3a6b4bad5b25d18cfb7285f65a6d60
         | 
| @@ -9,7 +9,7 @@ module ItunesReceiptDecoder | |
| 9 9 | 
             
                class Base
         | 
| 10 10 | 
             
                  ##
         | 
| 11 11 | 
             
                  # The raw receipt, i.e. not base64 encoded
         | 
| 12 | 
            -
                  attr_reader :raw_receipt, :options
         | 
| 12 | 
            +
                  attr_reader :raw_receipt, :receipt, :options, :style, :environment
         | 
| 13 13 |  | 
| 14 14 | 
             
                  ##
         | 
| 15 15 | 
             
                  # Initializes with a raw (base64 decoded receipt)
         | 
| @@ -20,12 +20,7 @@ module ItunesReceiptDecoder | |
| 20 20 | 
             
                  def initialize(raw_receipt, options = {})
         | 
| 21 21 | 
             
                    @raw_receipt = raw_receipt
         | 
| 22 22 | 
             
                    @options = options
         | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
                  ##
         | 
| 26 | 
            -
                  # Returns the receipt receipt properties
         | 
| 27 | 
            -
                  def receipt
         | 
| 28 | 
            -
                    decode && @receipt
         | 
| 23 | 
            +
                    decode
         | 
| 29 24 | 
             
                  end
         | 
| 30 25 |  | 
| 31 26 | 
             
                  ##
         | 
| @@ -7,35 +7,37 @@ module ItunesReceiptDecoder | |
| 7 7 | 
             
                ##
         | 
| 8 8 | 
             
                # ItunesReceiptDecoder::Decode::TransactionReceipt
         | 
| 9 9 | 
             
                class TransactionReceipt < Base
         | 
| 10 | 
            -
                   | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
                    @receipt ||= purchase_info
         | 
| 14 | 
            -
                    self
         | 
| 10 | 
            +
                  def initialize(raw_receipt, options = {})
         | 
| 11 | 
            +
                    @style = :transaction
         | 
| 12 | 
            +
                    super
         | 
| 15 13 | 
             
                  end
         | 
| 16 14 |  | 
| 17 | 
            -
                   | 
| 18 | 
            -
                  # Just returns :transaction
         | 
| 19 | 
            -
                  def style
         | 
| 20 | 
            -
                    :transaction
         | 
| 21 | 
            -
                  end
         | 
| 15 | 
            +
                  private
         | 
| 22 16 |  | 
| 23 | 
            -
                   | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 17 | 
            +
                  def decode
         | 
| 18 | 
            +
                    @receipt = parse_purchase_info
         | 
| 19 | 
            +
                    @environment = payload.fetch('environment')
         | 
| 20 | 
            +
                  rescue KeyError => e
         | 
| 21 | 
            +
                    raise DecodingError, e.message
         | 
| 27 22 | 
             
                  end
         | 
| 28 23 |  | 
| 29 | 
            -
                   | 
| 30 | 
            -
             | 
| 31 | 
            -
                  def purchase_info
         | 
| 32 | 
            -
                    contents = Base64.strict_decode64(payload['purchase-info'])
         | 
| 33 | 
            -
                    result = parse_plist(contents)
         | 
| 34 | 
            -
                    result.keys.each do |key|
         | 
| 24 | 
            +
                  def parse_purchase_info
         | 
| 25 | 
            +
                    purchase_info.keys.each do |key|
         | 
| 35 26 | 
             
                      new_key = key.tr('-', '_').to_sym
         | 
| 36 | 
            -
                       | 
| 27 | 
            +
                      purchase_info[new_key] = purchase_info.delete(key)
         | 
| 37 28 | 
             
                    end
         | 
| 38 | 
            -
                     | 
| 29 | 
            +
                    purchase_info
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def purchase_info
         | 
| 33 | 
            +
                    return @purchase_info if @purchase_info
         | 
| 34 | 
            +
                    contents = Base64.strict_decode64 payload.fetch('purchase-info')
         | 
| 35 | 
            +
                  rescue KeyError => e
         | 
| 36 | 
            +
                    raise DecodingError, e.message
         | 
| 37 | 
            +
                  rescue ArgumentError => e
         | 
| 38 | 
            +
                    raise DecodingError, e.message
         | 
| 39 | 
            +
                  else
         | 
| 40 | 
            +
                    @purchase_info = parse_plist(contents)
         | 
| 39 41 | 
             
                  end
         | 
| 40 42 |  | 
| 41 43 | 
             
                  def payload
         | 
| @@ -44,7 +46,9 @@ module ItunesReceiptDecoder | |
| 44 46 |  | 
| 45 47 | 
             
                  def parse_plist(contents)
         | 
| 46 48 | 
             
                    plist = CFPropertyList::List.new(data: contents)
         | 
| 47 | 
            -
                    CFPropertyList.native_types(plist.value)
         | 
| 49 | 
            +
                    hash = CFPropertyList.native_types(plist.value)
         | 
| 50 | 
            +
                    fail DecodingError, 'hash not found in plist' unless hash.is_a?(Hash)
         | 
| 51 | 
            +
                    hash
         | 
| 48 52 | 
             
                  end
         | 
| 49 53 | 
             
                end
         | 
| 50 54 | 
             
              end
         | 
| @@ -34,27 +34,18 @@ module ItunesReceiptDecoder | |
| 34 34 | 
             
                                        original_purchase_date expires_date
         | 
| 35 35 | 
             
                                        cancellation_date)
         | 
| 36 36 |  | 
| 37 | 
            -
                   | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
                    @receipt ||= parse_app_receipt_fields(payload.value)
         | 
| 41 | 
            -
                    self
         | 
| 37 | 
            +
                  def initialize(raw_receipt, options = {})
         | 
| 38 | 
            +
                    @style = :unified
         | 
| 39 | 
            +
                    super
         | 
| 42 40 | 
             
                  end
         | 
| 43 41 |  | 
| 44 | 
            -
                   | 
| 45 | 
            -
                  # Just returns :unified
         | 
| 46 | 
            -
                  def style
         | 
| 47 | 
            -
                    :unified
         | 
| 48 | 
            -
                  end
         | 
| 42 | 
            +
                  private
         | 
| 49 43 |  | 
| 50 | 
            -
                   | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
                    decode.receipt[:environment]
         | 
| 44 | 
            +
                  def decode
         | 
| 45 | 
            +
                    @receipt = parse_app_receipt_fields(payload.value)
         | 
| 46 | 
            +
                    @environment = @receipt.fetch(:environment, nil)
         | 
| 54 47 | 
             
                  end
         | 
| 55 48 |  | 
| 56 | 
            -
                  private
         | 
| 57 | 
            -
             | 
| 58 49 | 
             
                  def parse_app_receipt_fields(fields)
         | 
| 59 50 | 
             
                    result = {}
         | 
| 60 51 | 
             
                    fields.each do |seq|
         | 
| @@ -93,14 +84,18 @@ module ItunesReceiptDecoder | |
| 93 84 |  | 
| 94 85 | 
             
                  def payload
         | 
| 95 86 | 
             
                    verify && OpenSSL::ASN1.decode(pkcs7.data)
         | 
| 87 | 
            +
                  rescue OpenSSL::ASN1::ASN1Error => e
         | 
| 88 | 
            +
                    raise DecodingError, e.message
         | 
| 96 89 | 
             
                  end
         | 
| 97 90 |  | 
| 98 91 | 
             
                  def verify
         | 
| 99 | 
            -
                    pkcs7.verify | 
| 92 | 
            +
                    pkcs7.verify [], OpenSSL::X509::Store.new, nil, OpenSSL::PKCS7::NOVERIFY
         | 
| 100 93 | 
             
                  end
         | 
| 101 94 |  | 
| 102 95 | 
             
                  def pkcs7
         | 
| 103 96 | 
             
                    @pkcs7 ||= OpenSSL::PKCS7.new(raw_receipt)
         | 
| 97 | 
            +
                  rescue ArgumentError => e
         | 
| 98 | 
            +
                    raise DecodingError, e.message
         | 
| 104 99 | 
             
                  end
         | 
| 105 100 | 
             
                end
         | 
| 106 101 | 
             
              end
         | 
| @@ -3,7 +3,6 @@ require 'base64' | |
| 3 3 | 
             
            require 'openssl'
         | 
| 4 4 | 
             
            require 'cfpropertylist'
         | 
| 5 5 | 
             
            require 'itunes_receipt_decoder/version'
         | 
| 6 | 
            -
            require 'itunes_receipt_decoder/config'
         | 
| 7 6 | 
             
            require 'itunes_receipt_decoder/decode/base'
         | 
| 8 7 | 
             
            require 'itunes_receipt_decoder/decode/transaction_receipt'
         | 
| 9 8 | 
             
            require 'itunes_receipt_decoder/decode/unified_receipt'
         | 
| @@ -11,6 +10,8 @@ require 'itunes_receipt_decoder/decode/unified_receipt' | |
| 11 10 | 
             
            ##
         | 
| 12 11 | 
             
            # ItunesReceiptDecoder
         | 
| 13 12 | 
             
            module ItunesReceiptDecoder
         | 
| 13 | 
            +
              class DecodingError < StandardError; end
         | 
| 14 | 
            +
             | 
| 14 15 | 
             
              ##
         | 
| 15 16 | 
             
              # Initializes either ItunesReceiptDecoder::Decode::Transaction or
         | 
| 16 17 | 
             
              # ItunesReceiptDecoder::Decode::Unified with the base64 encoded receipt
         | 
| @@ -20,6 +21,9 @@ module ItunesReceiptDecoder | |
| 20 21 | 
             
              # * +options+ - optional arguments
         | 
| 21 22 | 
             
              def self.new(receipt_data, options = {})
         | 
| 22 23 | 
             
                raw_receipt = Base64.strict_decode64(receipt_data)
         | 
| 24 | 
            +
              rescue ArgumentError => e
         | 
| 25 | 
            +
                raise DecodingError, e.message
         | 
| 26 | 
            +
              else
         | 
| 23 27 | 
             
                if /^\{*+\}$/ =~ raw_receipt
         | 
| 24 28 | 
             
                  Decode::TransactionReceipt.new(raw_receipt, options)
         | 
| 25 29 | 
             
                else
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: itunes_receipt_decoder
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - mbaasy.com
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015- | 
| 11 | 
            +
            date: 2015-11-19 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: CFPropertyList
         | 
| @@ -67,47 +67,47 @@ dependencies: | |
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 68 | 
             
                    version: '0.2'
         | 
| 69 69 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            -
              name:  | 
| 70 | 
            +
              name: simplecov
         | 
| 71 71 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                requirements:
         | 
| 73 73 | 
             
                - - "~>"
         | 
| 74 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            -
                    version: '0. | 
| 75 | 
            +
                    version: '0.10'
         | 
| 76 76 | 
             
              type: :development
         | 
| 77 77 | 
             
              prerelease: false
         | 
| 78 78 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 79 | 
             
                requirements:
         | 
| 80 80 | 
             
                - - "~>"
         | 
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            -
                    version: '0. | 
| 82 | 
            +
                    version: '0.10'
         | 
| 83 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            -
              name:  | 
| 84 | 
            +
              name: codeclimate-test-reporter
         | 
| 85 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 86 | 
             
                requirements:
         | 
| 87 87 | 
             
                - - "~>"
         | 
| 88 88 | 
             
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            -
                    version: '0. | 
| 89 | 
            +
                    version: '0.4'
         | 
| 90 90 | 
             
              type: :development
         | 
| 91 91 | 
             
              prerelease: false
         | 
| 92 92 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 93 | 
             
                requirements:
         | 
| 94 94 | 
             
                - - "~>"
         | 
| 95 95 | 
             
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            -
                    version: '0. | 
| 96 | 
            +
                    version: '0.4'
         | 
| 97 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 98 | 
            -
              name:  | 
| 98 | 
            +
              name: rubocop
         | 
| 99 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 100 | 
             
                requirements:
         | 
| 101 101 | 
             
                - - "~>"
         | 
| 102 102 | 
             
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            -
                    version: ' | 
| 103 | 
            +
                    version: '0.33'
         | 
| 104 104 | 
             
              type: :development
         | 
| 105 105 | 
             
              prerelease: false
         | 
| 106 106 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 107 | 
             
                requirements:
         | 
| 108 108 | 
             
                - - "~>"
         | 
| 109 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            -
                    version: ' | 
| 110 | 
            +
                    version: '0.33'
         | 
| 111 111 | 
             
            description: |2
         | 
| 112 112 | 
             
                  Decode iTunes OS X and iOS receipts without remote server-side validation
         | 
| 113 113 | 
             
                  by using the Apple Inc Root Certificate.
         | 
| @@ -117,7 +117,6 @@ extensions: [] | |
| 117 117 | 
             
            extra_rdoc_files: []
         | 
| 118 118 | 
             
            files:
         | 
| 119 119 | 
             
            - lib/itunes_receipt_decoder.rb
         | 
| 120 | 
            -
            - lib/itunes_receipt_decoder/config.rb
         | 
| 121 120 | 
             
            - lib/itunes_receipt_decoder/decode/base.rb
         | 
| 122 121 | 
             
            - lib/itunes_receipt_decoder/decode/transaction_receipt.rb
         | 
| 123 122 | 
             
            - lib/itunes_receipt_decoder/decode/unified_receipt.rb
         | 
| @@ -1,29 +0,0 @@ | |
| 1 | 
            -
            ##
         | 
| 2 | 
            -
            # ItunesReceiptDecoder
         | 
| 3 | 
            -
            module ItunesReceiptDecoder
         | 
| 4 | 
            -
              ##
         | 
| 5 | 
            -
              # ItunesReceiptDecoder::Config
         | 
| 6 | 
            -
              class Config
         | 
| 7 | 
            -
                class << self
         | 
| 8 | 
            -
                  ##
         | 
| 9 | 
            -
                  # Set this to the path of the AppleIncRootCertificate.cer file
         | 
| 10 | 
            -
                  attr_accessor :certificate_path
         | 
| 11 | 
            -
                end
         | 
| 12 | 
            -
             | 
| 13 | 
            -
                ##
         | 
| 14 | 
            -
                # Returns the OpenSSL X509 Store for the certificate
         | 
| 15 | 
            -
                def self.certificate_store
         | 
| 16 | 
            -
                  return @certificate_store if @certificate_store
         | 
| 17 | 
            -
                  @certificate_store = OpenSSL::X509::Store.new
         | 
| 18 | 
            -
                  @certificate_store.add_cert(certificate)
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                ##
         | 
| 22 | 
            -
                # returns the OpenSSL X509 Certificate
         | 
| 23 | 
            -
                def self.certificate
         | 
| 24 | 
            -
                  @certificate ||= OpenSSL::X509::Certificate.new(
         | 
| 25 | 
            -
                    File.read(certificate_path)
         | 
| 26 | 
            -
                  )
         | 
| 27 | 
            -
                end
         | 
| 28 | 
            -
              end
         | 
| 29 | 
            -
            end
         |