itunes_receipt_decoder 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64a4d44ac99c4a2f403abce0757f8d2967fb892f
4
- data.tar.gz: 4fb7ac5d8944a5179aa948b81896656f0a184486
3
+ metadata.gz: 3af07c85acedd565c74e51d29053205b49134fd4
4
+ data.tar.gz: 5da51cb846cacc7a182f4938147835744ce2149d
5
5
  SHA512:
6
- metadata.gz: c0dad4a0219e4e283733abc18e025eeb7c338bec797797a14dc5bc4d1c97af26287b4f81c2e3b80b914f6b699cbc4ed90067edcedc2b38c12f89ec2c7f0f539b
7
- data.tar.gz: 36e8317e6cd14c12828f60a7e886630dabe791c61d188a23af5006ba4ac8020a1792f8834b1e6704d27fc5d29e8bdc72e1307d998515cc7036ae7c75a336a137
6
+ metadata.gz: bc3acb82230669e4633a443ecec9c4c6115879c205f3c790d282360fa7734a31606730d5d0241b29be8a017f68fa9b46efed58d56af001c726cd35ba16b410cd
7
+ data.tar.gz: 665a657a448c447a1c22e03a8a9a1049ca9cffc55db5f2dccaf32e67a130863d60bb7adee2334dbf2e42a850102e914bc05e63dda6a7584dc6198a818fc0d7bf
@@ -0,0 +1,29 @@
1
+ ##
2
+ # ItunesReceiptDecoder
3
+ module ItunesReceiptDecoder
4
+ ##
5
+ # ItunesReceiptDecoder::Decode
6
+ module Decode
7
+ ##
8
+ # ItunesReceiptDecoder::Decode::Base
9
+ class Base
10
+ attr_reader :raw_receipt
11
+
12
+ def initialize(raw_receipt)
13
+ @raw_receipt = raw_receipt
14
+ end
15
+
16
+ def receipt
17
+ decode && @receipt
18
+ end
19
+
20
+ def production?
21
+ environment == 'Production'
22
+ end
23
+
24
+ def sandbox?
25
+ !production?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,45 @@
1
+ ##
2
+ # ItunesReceiptDecoder
3
+ module ItunesReceiptDecoder
4
+ ##
5
+ # ItunesReceiptDecoder::Decode
6
+ module Decode
7
+ ##
8
+ # ItunesReceiptDecoder::Decode::TransactionReceipt
9
+ class TransactionReceipt < Base
10
+ def decode
11
+ @receipt ||= purchase_info
12
+ self
13
+ end
14
+
15
+ def style
16
+ :transaction
17
+ end
18
+
19
+ def environment
20
+ payload['environment']
21
+ end
22
+
23
+ private
24
+
25
+ def purchase_info
26
+ contents = Base64.strict_decode64(payload['purchase-info'])
27
+ result = parse_plist(contents)
28
+ result.keys.each do |key|
29
+ new_key = key.tr('-', '_').to_sym
30
+ result[new_key] = result.delete(key)
31
+ end
32
+ result
33
+ end
34
+
35
+ def payload
36
+ @payload ||= parse_plist(raw_receipt)
37
+ end
38
+
39
+ def parse_plist(contents)
40
+ plist = CFPropertyList::List.new(data: contents)
41
+ CFPropertyList.native_types(plist.value)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,77 @@
1
+ ##
2
+ # ItunesReceiptDecoder
3
+ module ItunesReceiptDecoder
4
+ ##
5
+ # ItunesReceiptDecoder::Decode
6
+ module Decode
7
+ ##
8
+ # ItunesReceiptDecoder::Decode::UnifiedReceipt
9
+ class UnifiedReceipt < Base
10
+ RECEIPT_FIELDS = {
11
+ 0 => :environment,
12
+ 2 => :bundle_id,
13
+ 3 => :application_version,
14
+ 12 => :creation_date,
15
+ 17 => :in_app,
16
+ 19 => :original_application_version,
17
+ 21 => :expiration_date,
18
+ 1701 => :quantity,
19
+ 1702 => :product_id,
20
+ 1703 => :transaction_id,
21
+ 1705 => :original_transaction_id,
22
+ 1704 => :purchase_date,
23
+ 1706 => :original_purchase_date,
24
+ 1708 => :expires_date,
25
+ 1712 => :cancellation_date,
26
+ 1711 => :web_order_line_item_id
27
+ }
28
+
29
+ def decode
30
+ @receipt ||= parse_app_receipt_fields(payload.value)
31
+ self
32
+ end
33
+
34
+ def style
35
+ :unified
36
+ end
37
+
38
+ def environment
39
+ decode.receipt[:environment]
40
+ end
41
+
42
+ private
43
+
44
+ def parse_app_receipt_fields(fields)
45
+ result = {}
46
+ fields.each do |seq|
47
+ type, _version, value = seq.value.map(&:value)
48
+ next unless (field = RECEIPT_FIELDS[type.to_i])
49
+ build_result(result, field, value)
50
+ end
51
+ result
52
+ end
53
+
54
+ def build_result(result, field, value)
55
+ value = OpenSSL::ASN1.decode(value).value
56
+ case field
57
+ when :in_app
58
+ (result[field] ||= []).push(parse_app_receipt_fields(value))
59
+ else
60
+ result[field] = value.class == OpenSSL::BN ? value.to_i : value.to_s
61
+ end
62
+ end
63
+
64
+ def payload
65
+ verify && OpenSSL::ASN1.decode(pkcs7.data)
66
+ end
67
+
68
+ def verify
69
+ pkcs7.verify(nil, Config.certificate_store, nil, nil)
70
+ end
71
+
72
+ def pkcs7
73
+ @pkcs7 ||= OpenSSL::PKCS7.new(raw_receipt)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,5 +1,5 @@
1
1
  ##
2
2
  # ItunesReceiptDecoder
3
3
  module ItunesReceiptDecoder
4
- VERSION = '0.0.2'
4
+ VERSION = '0.1.0'
5
5
  end
@@ -1,11 +1,21 @@
1
- require 'time'
2
1
  require 'base64'
3
2
  require 'openssl'
3
+ require 'cfpropertylist'
4
4
  require 'itunes_receipt_decoder/version'
5
5
  require 'itunes_receipt_decoder/config'
6
- require 'itunes_receipt_decoder/decode'
6
+ require 'itunes_receipt_decoder/decode/base'
7
+ require 'itunes_receipt_decoder/decode/transaction_receipt'
8
+ require 'itunes_receipt_decoder/decode/unified_receipt'
7
9
 
8
10
  ##
9
11
  # ItunesReceiptDecoder
10
12
  module ItunesReceiptDecoder
13
+ def self.new(receipt_data)
14
+ raw_receipt = Base64.strict_decode64(receipt_data)
15
+ if /^\{*+\}$/ =~ raw_receipt
16
+ Decode::TransactionReceipt.new(raw_receipt)
17
+ else
18
+ Decode::UnifiedReceipt.new(raw_receipt)
19
+ end
20
+ end
11
21
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itunes_receipt_decoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.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-10-23 00:00:00.000000000 Z
11
+ date: 2015-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: CFPropertyList
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.3'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rake
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -104,7 +118,9 @@ extra_rdoc_files: []
104
118
  files:
105
119
  - lib/itunes_receipt_decoder.rb
106
120
  - lib/itunes_receipt_decoder/config.rb
107
- - lib/itunes_receipt_decoder/decode.rb
121
+ - lib/itunes_receipt_decoder/decode/base.rb
122
+ - lib/itunes_receipt_decoder/decode/transaction_receipt.rb
123
+ - lib/itunes_receipt_decoder/decode/unified_receipt.rb
108
124
  - lib/itunes_receipt_decoder/version.rb
109
125
  homepage: https://github.com/mbaasy/itunes_receipt_decoder
110
126
  licenses:
@@ -1,74 +0,0 @@
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