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
|