itunes_receipt_decoder 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 64a4d44ac99c4a2f403abce0757f8d2967fb892f
4
+ data.tar.gz: 4fb7ac5d8944a5179aa948b81896656f0a184486
5
+ SHA512:
6
+ metadata.gz: c0dad4a0219e4e283733abc18e025eeb7c338bec797797a14dc5bc4d1c97af26287b4f81c2e3b80b914f6b699cbc4ed90067edcedc2b38c12f89ec2c7f0f539b
7
+ data.tar.gz: 36e8317e6cd14c12828f60a7e886630dabe791c61d188a23af5006ba4ac8020a1792f8834b1e6704d27fc5d29e8bdc72e1307d998515cc7036ae7c75a336a137
@@ -0,0 +1,11 @@
1
+ require 'time'
2
+ require 'base64'
3
+ require 'openssl'
4
+ require 'itunes_receipt_decoder/version'
5
+ require 'itunes_receipt_decoder/config'
6
+ require 'itunes_receipt_decoder/decode'
7
+
8
+ ##
9
+ # ItunesReceiptDecoder
10
+ module ItunesReceiptDecoder
11
+ end
@@ -0,0 +1,23 @@
1
+ ##
2
+ # ItunesReceiptDecoder
3
+ module ItunesReceiptDecoder
4
+ ##
5
+ # ItunesReceiptDecoder::Config
6
+ class Config
7
+ class << self
8
+ attr_accessor :certificate_path
9
+ end
10
+
11
+ def self.certificate_store
12
+ return @certificate_store if @certificate_store
13
+ @certificate_store = OpenSSL::X509::Store.new
14
+ @certificate_store.add_cert(certificate)
15
+ end
16
+
17
+ def self.certificate
18
+ @certificate ||= OpenSSL::X509::Certificate.new(
19
+ File.read(certificate_path)
20
+ )
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,74 @@
1
+ ##
2
+ # ItunesReceiptDecoder
3
+ module ItunesReceiptDecoder
4
+ ##
5
+ # ItunesReceiptDecoder::Decode
6
+ class Decode
7
+ RECEIPT_FIELDS = {
8
+ 0 => :environment,
9
+ 2 => :bundle_id,
10
+ 3 => :application_version,
11
+ 12 => :creation_date,
12
+ 17 => :in_app,
13
+ 19 => :original_application_version,
14
+ 21 => :expiration_date,
15
+ 1701 => :quantity,
16
+ 1702 => :product_id,
17
+ 1703 => :transaction_id,
18
+ 1705 => :original_transaction_id,
19
+ 1704 => :purchase_date,
20
+ 1706 => :original_purchase_date,
21
+ 1708 => :expires_date,
22
+ 1712 => :cancellation_date,
23
+ 1711 => :web_order_line_item_id
24
+ }
25
+
26
+ attr_accessor :receipt_data
27
+ attr_accessor :receipt
28
+
29
+ def initialize(receipt_data)
30
+ @receipt_data = Base64.strict_decode64(receipt_data)
31
+ @receipt = {}
32
+ end
33
+
34
+ def decode
35
+ self.receipt = parse_app_receipt_fields(payload.value)
36
+ end
37
+
38
+ private
39
+
40
+ def parse_app_receipt_fields(fields)
41
+ result = {}
42
+ fields.each do |seq|
43
+ type, _version, value = seq.value.map(&:value)
44
+ next unless (field = RECEIPT_FIELDS[type.to_i])
45
+ build_result(result, field, value)
46
+ end
47
+ result
48
+ end
49
+
50
+ def build_result(result, field, value)
51
+ value = OpenSSL::ASN1.decode(value).value
52
+ case field
53
+ when :in_app
54
+ (result[field] ||= []).push(parse_app_receipt_fields(value))
55
+ when :creation_date, :expiration_date, :purchase_date,
56
+ :original_purchase_date, :expires_date, :cancellation_date
57
+ result[field] = value.empty? ? nil : Time.parse(value).utc
58
+ else
59
+ result[field] = value.class == OpenSSL::BN ? value.to_i : value.to_s
60
+ end
61
+ end
62
+
63
+ def payload
64
+ @payload ||= OpenSSL::ASN1.decode(pkcs7.data)
65
+ end
66
+
67
+ def pkcs7
68
+ return @pkcs7 if @pkcs7
69
+ @pkcs7 = OpenSSL::PKCS7.new(receipt_data)
70
+ @pkcs7.verify(nil, Config.certificate_store, nil, nil)
71
+ @pkcs7
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,5 @@
1
+ ##
2
+ # ItunesReceiptDecoder
3
+ module ItunesReceiptDecoder
4
+ VERSION = '0.0.2'
5
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: itunes_receipt_decoder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - mbaasy.com
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.4'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubygems-tasks
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: codeclimate-test-reporter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.33'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.33'
83
+ - !ruby/object:Gem::Dependency
84
+ name: awesome_print
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.6'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.6'
97
+ description: |2
98
+ Decode iTunes OS X and iOS receipts without remote server-side validation
99
+ by using the Apple Inc Root Certificate.
100
+ email: hello@mbaasy.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - lib/itunes_receipt_decoder.rb
106
+ - lib/itunes_receipt_decoder/config.rb
107
+ - lib/itunes_receipt_decoder/decode.rb
108
+ - lib/itunes_receipt_decoder/version.rb
109
+ homepage: https://github.com/mbaasy/itunes_receipt_decoder
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: 1.9.2
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.4.6
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Decode iTunes OS X and iOS receipts
133
+ test_files: []
134
+ has_rdoc: