tcat 0.1.9 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d08abb934b373088d1c95b04871fa30e9feb3a380b3e9fbed9011b659cb5da4a
4
- data.tar.gz: ab23c8913af3b3ec2c0687f9715a0f7e983e3349183cd42c66e0d040208acd90
3
+ metadata.gz: e76a787a4383f06dec67ec0b8ec9baf2dbb139957a4ac3db2c38eed7ce02776f
4
+ data.tar.gz: c644618ec3ed543248ad46b3a85b717106c47dd5bb70490f21f9588dd91fe1a2
5
5
  SHA512:
6
- metadata.gz: 26e31aeaa06a46d31d7bea49fd46999bd446d47d29e73011a3262627a0658f0344123085b4f67000dde3f4aeb14611019d10463215f672413ed64b74717561a1
7
- data.tar.gz: d6634d7f3ecfb4a14795d55e6a7ae42d38002d52382fa89620461edd5a35b858dec1526db2ea24d1689aa78e22aa942f196cd13632cd45688da4ab3e6f2f3152
6
+ metadata.gz: 0c28c7427eb444be87caee855801fe5fafa407353357eb72134d12dd30a093430c0f3ef7eaa4fff103064245a043cc61d3401ea547202763fd2ebca7ce7f0225
7
+ data.tar.gz: 073af2539f7f83740ec39f1433514044be8ec98bda42b6e01ac263c4869080a40e4b225fdd8df981e4a7be6398d976465c186f805420414a6fff9d2da9c5051e
data/README.md CHANGED
@@ -58,6 +58,7 @@ status = query.status_code
58
58
  # :in_transit - In transit
59
59
  # :returned - Return completed
60
60
  # :held - Held at post office
61
+ # :rescheduled - Delivery time rescheduled
61
62
  # :forwarding - Being forwarded
62
63
  # :investigation - Under investigation
63
64
  # :rejected - Delivery rejected
@@ -92,6 +93,7 @@ end
92
93
  - `:in_transit` - In transit
93
94
  - `:returned` - Return completed
94
95
  - `:held` - Package is being held at post office
96
+ - `:rescheduled` - Delivery time rescheduled
95
97
  - `:forwarding` - Package is being forwarded
96
98
  - `:investigation` - Package is under investigation (e.g., address change, rejection)
97
99
  - `:rejected` - Delivery was rejected
@@ -128,6 +130,21 @@ This gem is available as open source under the terms of the [MIT License](https:
128
130
 
129
131
  ## Changelog
130
132
 
133
+ ### 0.2.0
134
+
135
+ - Fixed SSL certificate verification issues with T-Cat API
136
+ - Added session initialization to obtain cookies before queries
137
+ - Added cookie management for maintaining session state
138
+ - Added new status code mappings: `:rescheduled` (另約時間) and `:held` (暫置營業所)
139
+ - Removed Rails.logger dependency for better standalone gem compatibility
140
+ - Added base64 gem dependency for Ruby 3.4+ compatibility
141
+ - Updated HTTP headers to match latest BlackCat iOS app (version 3)
142
+ - Improved error handling with better debug output
143
+
144
+ ### 0.1.9
145
+
146
+ - Updated User-Agent and API version
147
+
131
148
  ### 0.1.7
132
149
 
133
150
  - Improved method naming, removed get_ prefix
@@ -143,7 +160,7 @@ This gem is available as open source under the terms of the [MIT License](https:
143
160
  - Improved error handling
144
161
  - Added test coverage
145
162
 
146
- ### 0.1.5 (2024-01-11)
163
+ ### 0.1.5
147
164
 
148
165
  - Refactored HTTP request handling with new HttpClient class
149
166
  - Refactored encryption logic with new EncryptionService class
@@ -1,13 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'net/http'
4
+ require 'openssl'
4
5
 
5
6
  module Tcat
6
7
  class HttpClient
7
8
  DEFAULT_HEADERS = {
8
- 'User-Agent' => 'BlackCat/2.49.1 (iPhone; iOS 18.4.1; Scale/3.00)',
9
- 'Accept-Language' => 'zh-Hant-TW;q=1, en-TW;q=0.9',
10
- 'Cookie' => 'citrix_ns_id=AAE7go4rZDusCRcEAAAAADuVBLGLdqo1FolMO02r_jOEnjNmr4u9sIYwtllmmfsOOw==KJArZA==AQJLxyeLYOXPo3Uzfh_rWrr_NcU=; ASP.NET_SessionId=p4v1z4nijrynbortgf4iqml4'
9
+ 'User-Agent' => 'BlackCat/3 (iPhone; iOS 26.2; Scale/3.00)',
10
+ 'Accept-Language' => 'en-TW;q=1, zh-Hant-TW;q=0.9',
11
+ 'Accept' => '*/*',
12
+ 'Accept-Encoding' => 'gzip, deflate, br',
13
+ 'Connection' => 'keep-alive'
11
14
  }.freeze
12
15
 
13
16
  API_ENDPOINT = 'https://www.t-cat.com.tw/iPhone/TCatApp.aspx'
@@ -15,8 +18,11 @@ module Tcat
15
18
 
16
19
  class RequestError < StandardError; end
17
20
 
21
+ attr_reader :cookies
22
+
18
23
  def initialize(timeout: 30)
19
24
  @timeout = timeout
25
+ @cookies = {}
20
26
  end
21
27
 
22
28
  def post(params)
@@ -25,9 +31,13 @@ module Tcat
25
31
 
26
32
  request = Net::HTTP::Post.new(uri)
27
33
  DEFAULT_HEADERS.each { |key, value| request[key] = value }
34
+ request['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'
35
+ request['Cookie'] = build_cookie_header if @cookies.any?
28
36
  request.body = URI.encode_www_form(params)
29
37
 
30
- handle_response(http.request(request))
38
+ response = http.request(request)
39
+ extract_cookies(response)
40
+ handle_response(response)
31
41
  rescue Net::ReadTimeout, Net::OpenTimeout => e
32
42
  raise RequestError, "Request timeout: #{e.message}"
33
43
  rescue SocketError, Net::HTTPError => e
@@ -36,11 +46,29 @@ module Tcat
36
46
  raise RequestError, "Unexpected error: #{e.message}"
37
47
  end
38
48
 
49
+ def initialize_session(secret)
50
+ params = {
51
+ f: 18,
52
+ secret: secret,
53
+ SVC: 'TCATAPP'
54
+ }
55
+ post(params)
56
+ end
57
+
39
58
  private
40
59
 
41
60
  def setup_http_client(uri)
42
61
  http = Net::HTTP.new(uri.host, uri.port)
43
62
  http.use_ssl = true
63
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
64
+
65
+ # Setup certificate store without CRL checking
66
+ # This verifies the certificate chain but skips CRL validation
67
+ store = OpenSSL::X509::Store.new
68
+ store.set_default_paths
69
+ # Explicitly do not set V_FLAG_CRL_CHECK or V_FLAG_CRL_CHECK_ALL
70
+ http.cert_store = store
71
+
44
72
  http.read_timeout = @timeout
45
73
  http.open_timeout = @timeout
46
74
  http
@@ -56,5 +84,20 @@ module Tcat
56
84
  raise RequestError, "HTTP #{response.code}: #{response.message}"
57
85
  end
58
86
  end
87
+
88
+ def extract_cookies(response)
89
+ return unless response['Set-Cookie']
90
+
91
+ response.get_fields('Set-Cookie').each do |cookie_string|
92
+ cookie_string.split(';').first.split(',').each do |pair|
93
+ name, value = pair.strip.split('=', 2)
94
+ @cookies[name] = value if name && value
95
+ end
96
+ end
97
+ end
98
+
99
+ def build_cookie_header
100
+ @cookies.map { |name, value| "#{name}=#{value}" }.join('; ')
101
+ end
59
102
  end
60
103
  end
data/lib/tcat/query.rb CHANGED
@@ -19,6 +19,9 @@ module Tcat
19
19
  @tracking_number = tracking_number
20
20
  @http_client = HttpClient.new
21
21
  @encryption_service = EncryptionService.new(@secret_key)
22
+
23
+ # Initialize session to get cookies
24
+ initialize_session
22
25
  end
23
26
 
24
27
  # Get current delivery status code
@@ -41,7 +44,7 @@ module Tcat
41
44
  extract_delivery_history(result)
42
45
  end
43
46
  rescue StandardError => e
44
- Rails.logger.error("Error getting delivery history: #{e.message}")
47
+ warn "Error getting delivery history: #{e.message}" if $DEBUG
45
48
  []
46
49
  end
47
50
 
@@ -60,6 +63,18 @@ module Tcat
60
63
  raise ArgumentError, 'SECRET_KEY must be configured' if @secret_key.nil? || @secret_key.empty?
61
64
  end
62
65
 
66
+ def initialize_session
67
+ secret = generate_secret
68
+ @http_client.initialize_session(secret)
69
+ warn "Session initialized, cookies: #{@http_client.cookies.inspect}" if $DEBUG
70
+ rescue HttpClient::RequestError => e
71
+ warn "Failed to initialize session: #{e.message}"
72
+ warn e.backtrace.first(5).join("\n") if $DEBUG
73
+ rescue StandardError => e
74
+ warn "Unexpected error during session initialization: #{e.class} - #{e.message}"
75
+ warn e.backtrace.first(5).join("\n") if $DEBUG
76
+ end
77
+
63
78
  def data
64
79
  {
65
80
  ConsignmentNo: @tracking_number,
@@ -99,7 +114,7 @@ module Tcat
99
114
 
100
115
  parse_status_message(delivery_statuses.uniq)
101
116
  rescue StandardError => e
102
- Rails.logger.error("Error parsing T-Cat response: #{e.message}")
117
+ warn "Error parsing T-Cat response: #{e.message}" if $DEBUG
103
118
  :error
104
119
  end
105
120
  end
@@ -115,7 +130,7 @@ module Tcat
115
130
  []
116
131
  end.compact.sort_by(&:time).reverse
117
132
  rescue StandardError => e
118
- Rails.logger.error("Error parsing delivery history: #{e.message}")
133
+ warn "Error parsing delivery history: #{e.message}" if $DEBUG
119
134
  []
120
135
  end
121
136
 
@@ -165,6 +180,8 @@ module Tcat
165
180
  '轉運中' => :in_transit,
166
181
  '退貨完成' => :returned,
167
182
  '暫置營業所保管中' => :held,
183
+ '暫置營業所' => :held,
184
+ '另約時間' => :rescheduled,
168
185
  '轉寄配送中' => :forwarding,
169
186
  '搬家(調查處理中)' => :investigation,
170
187
  '拒收(調查處理中)' => :investigation,
data/lib/tcat/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tcat
4
- VERSION = '0.1.9'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zac
@@ -9,6 +9,20 @@ bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.2.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.2.0
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: ox
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -78,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
92
  - !ruby/object:Gem::Version
79
93
  version: '0'
80
94
  requirements: []
81
- rubygems_version: 3.6.7
95
+ rubygems_version: 3.6.9
82
96
  specification_version: 4
83
97
  summary: A Ruby gem for tracking packages using the Tcat system.
84
98
  test_files: []