trustcaptcha 2.0.1 → 3.0.0.pre.beta.1

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: 2b1066bdda2e1ea42fcb98c6581371739df93d15a5cf3991a964e7cbc3e8dea5
4
- data.tar.gz: 9fabb687dce0e260c84a9cd70cf3dcd2277a231caf4e36a3f50071c8fb886b8b
3
+ metadata.gz: 10be47df90f618cc6611a61abc1a854103de387ab11485d5441792cb9020ef2b
4
+ data.tar.gz: d07f749734370f5389306497b494a0c4174a62a589a96642f12e5bff70ca9a56
5
5
  SHA512:
6
- metadata.gz: 430aa84c9874a746c6049a71cb021cc17352dd100eb0d487565cae7e3d5c6fbd359966031a539d6ac6ea74a1934d2518a66fa212bb0d8a5aca83830d670775c7
7
- data.tar.gz: 18681a24beffce50bfc2757658eec38c99fba9a4bbec097cbd2efa64149b55a0d4148394b9cad07ab3a52a6dddd26b845239cd986e9d01a463d022f0c10f8eb7
6
+ metadata.gz: 9124e75c419119f80641dd7c4a7740359872e01ffc771c840caae4cb7be8035818d3cc158663b47787d889052567d92048fa8433872f1576d8f4e455262c0a8d
7
+ data.tar.gz: 5be40a6a066b02c720969460754a7a322f6beb31de61f3be9b4b133ded5e4a3a15279c6135b458eeb948586704f948b1accae85102d85c16b75c47456d774d89
@@ -1,25 +1,35 @@
1
1
  require 'json'
2
2
 
3
3
  class VerificationResult
4
- attr_reader :captcha_id, :verification_id, :score, :reason, :mode, :origin, :ip_address,
5
- :device_family, :operating_system, :browser, :creation_timestamp,
6
- :release_timestamp, :retrieval_timestamp, :verification_passed
4
+ attr_reader :captcha_id, :verification_id, :verification_passed, :score,
5
+ :decision_type, :decision_action, :gateway_failover_active,
6
+ :risk_scoring_enabled, :minimal_data_mode_enabled,
7
+ :origin, :ip_address, :country_code,
8
+ :device_family, :operating_system, :browser,
9
+ :verification_started_at, :verification_finished_at,
10
+ :result_expires_at, :result_first_fetched_at, :result_last_fetched_at
7
11
 
8
12
  def initialize(data)
9
13
  @captcha_id = data['captchaId']
10
14
  @verification_id = data['verificationId']
15
+ @verification_passed = data['verificationPassed']
11
16
  @score = data['score']
12
- @reason = data['reason']
13
- @mode = data['mode']
17
+ @decision_type = data['decisionType']
18
+ @decision_action = data['decisionAction']
19
+ @gateway_failover_active = data['gatewayFailoverActive']
20
+ @risk_scoring_enabled = data['riskScoringEnabled']
21
+ @minimal_data_mode_enabled = data['minimalDataModeEnabled']
14
22
  @origin = data['origin']
15
23
  @ip_address = data['ipAddress']
24
+ @country_code = data['countryCode']
16
25
  @device_family = data['deviceFamily']
17
26
  @operating_system = data['operatingSystem']
18
27
  @browser = data['browser']
19
- @creation_timestamp = data['creationTimestamp']
20
- @release_timestamp = data['releaseTimestamp']
21
- @retrieval_timestamp = data['retrievalTimestamp']
22
- @verification_passed = data['verificationPassed']
28
+ @verification_started_at = data['verificationStartedAt']
29
+ @verification_finished_at = data['verificationFinishedAt']
30
+ @result_expires_at = data['resultExpiresAt']
31
+ @result_first_fetched_at = data['resultFirstFetchedAt']
32
+ @result_last_fetched_at = data['resultLastFetchedAt']
23
33
  end
24
34
 
25
35
  def self.from_json(json_data)
@@ -31,18 +41,24 @@ class VerificationResult
31
41
  {
32
42
  captchaId: @captcha_id,
33
43
  verificationId: @verification_id,
44
+ verificationPassed: @verification_passed,
34
45
  score: @score,
35
- reason: @reason,
36
- mode: @mode,
46
+ decisionType: @decision_type,
47
+ decisionAction: @decision_action,
48
+ gatewayFailoverActive: @gateway_failover_active,
49
+ riskScoringEnabled: @risk_scoring_enabled,
50
+ minimalDataModeEnabled: @minimal_data_mode_enabled,
37
51
  origin: @origin,
38
52
  ipAddress: @ip_address,
53
+ countryCode: @country_code,
39
54
  deviceFamily: @device_family,
40
55
  operatingSystem: @operating_system,
41
56
  browser: @browser,
42
- creationTimestamp: @creation_timestamp,
43
- releaseTimestamp: @release_timestamp,
44
- retrievalTimestamp: @retrieval_timestamp,
45
- verificationPassed: @verification_passed
57
+ verificationStartedAt: @verification_started_at,
58
+ verificationFinishedAt: @verification_finished_at,
59
+ resultExpiresAt: @result_expires_at,
60
+ resultFirstFetchedAt: @result_first_fetched_at,
61
+ resultLastFetchedAt: @result_last_fetched_at
46
62
  }.to_json
47
63
  end
48
64
  end
@@ -1,19 +1,19 @@
1
1
  require 'json'
2
- require 'securerandom'
3
2
  require 'base64'
4
3
 
5
4
  class VerificationToken
6
- attr_reader :api_endpoint, :verification_id
5
+ attr_reader :verification_id, :client_failover
7
6
 
8
- def initialize(api_endpoint, verification_id)
9
- @api_endpoint = api_endpoint
7
+ def initialize(verification_id, client_failover = false)
10
8
  @verification_id = verification_id
9
+ @client_failover = client_failover
11
10
  end
12
11
 
13
12
  def self.from_base64(base64_string)
14
13
  json_string = Base64.decode64(base64_string)
15
14
  data = JSON.parse(json_string)
16
- new(data['apiEndpoint'], data['verificationId'])
15
+ raise StandardError, 'Missing verificationId' if data['verificationId'].nil?
16
+ new(data['verificationId'], data['clientFailover'] == true)
17
17
  rescue StandardError => e
18
18
  raise e
19
19
  end
@@ -0,0 +1,98 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+ require 'base64'
5
+ require_relative 'model/verification_token'
6
+ require_relative 'model/verification_result'
7
+
8
+ class TrustCaptcha
9
+
10
+ LIBRARY_VERSION = '3.0.0'.freeze
11
+ LIBRARY_LANGUAGE = 'ruby'.freeze
12
+ DEFAULT_API_HOST = 'https://api.trustcomponent.com'.freeze
13
+ DEFAULT_CONNECT_TIMEOUT_S = 3
14
+ DEFAULT_READ_TIMEOUT_S = 5
15
+
16
+ class ApiKeyInvalidException < StandardError; end
17
+ class VerificationTokenInvalidException < StandardError; end
18
+ class VerificationNotFoundException < StandardError; end
19
+ class VerificationNotFinishedException < StandardError; end
20
+ class VerificationResultExpiredException < StandardError; end
21
+ class VerificationResultRetrievalLimitReachedException < StandardError; end
22
+ class FailoverException < StandardError; end
23
+ class ServerUnreachableException < FailoverException; end
24
+ class ClientReportedServerUnreachableException < FailoverException; end
25
+
26
+ def initialize(api_key,
27
+ api_host: DEFAULT_API_HOST,
28
+ connect_timeout_s: DEFAULT_CONNECT_TIMEOUT_S,
29
+ read_timeout_s: DEFAULT_READ_TIMEOUT_S,
30
+ proxy: nil)
31
+ raise ArgumentError, 'api_key must not be empty' if api_key.nil? || api_key.empty?
32
+ @api_key = api_key
33
+ @api_host = api_host
34
+ @connect_timeout_s = connect_timeout_s
35
+ @read_timeout_s = read_timeout_s
36
+ @proxy = proxy # Either a URI string ("http://host:port[/]") or nil.
37
+ end
38
+
39
+ def get_verification_result(base64_verification_token)
40
+ verification_token = parse_verification_token(base64_verification_token)
41
+ query = verification_token.client_failover ? '?clientFailover=true' : ''
42
+ url = URI("#{@api_host}/v2/verifications/#{verification_token.verification_id}/results#{query}")
43
+ headers = {
44
+ 'Authorization' => "Bearer #{@api_key}",
45
+ 'User-Agent' => self.class.build_user_agent,
46
+ }
47
+
48
+ http = if @proxy
49
+ p = URI.parse(@proxy)
50
+ Net::HTTP.new(url.host, url.port, p.host, p.port, p.user, p.password)
51
+ else
52
+ Net::HTTP.new(url.host, url.port)
53
+ end
54
+ http.use_ssl = url.scheme == 'https'
55
+ http.open_timeout = @connect_timeout_s
56
+ http.read_timeout = @read_timeout_s
57
+
58
+ response = begin
59
+ request = Net::HTTP::Get.new(url.request_uri, headers)
60
+ http.request(request)
61
+ rescue SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, Net::OpenTimeout, Net::ReadTimeout, Errno::ETIMEDOUT
62
+ raise ServerUnreachableException, 'Could not reach the TrustCaptcha server. This is a high-trust failover signal — your backend was unable to contact our servers.'
63
+ end
64
+
65
+ case response.code.to_i
66
+ when 403
67
+ raise ApiKeyInvalidException, 'The provided api key is invalid. Please verify the api key from your captcha settings.'
68
+ when 404
69
+ raise VerificationNotFoundException, 'No verification could be found for the given verification token.'
70
+ when 423
71
+ raise VerificationNotFinishedException, 'The verification is not yet completed. Please wait until the user has finished solving the captcha before requesting the result.'
72
+ when 410
73
+ raise VerificationResultExpiredException, 'The verification result has expired and can no longer be retrieved.'
74
+ when 412
75
+ raise ClientReportedServerUnreachableException, 'The client reported it could not reach the TrustCaptcha server, but the gateway has no record of a recent outage.'
76
+ when 429
77
+ raise VerificationResultRetrievalLimitReachedException, 'The verification result has reached its maximum retrieval count and can no longer be retrieved.'
78
+ else
79
+ raise "Failed to retrieve verification result: HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)
80
+ end
81
+
82
+ VerificationResult.from_json(response.body)
83
+ end
84
+
85
+ private
86
+
87
+ def parse_verification_token(base64_verification_token)
88
+ VerificationToken.from_base64(base64_verification_token)
89
+ rescue StandardError => e
90
+ raise VerificationTokenInvalidException, "The verification token is malformed or could not be parsed: #{e.message}"
91
+ end
92
+
93
+ def self.build_user_agent
94
+ payload = { 'language' => LIBRARY_LANGUAGE, 'version' => LIBRARY_VERSION }
95
+ encoded = Base64.strict_encode64(JSON.generate(payload))
96
+ "Trustcaptcha/#{encoded}"
97
+ end
98
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trustcaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0.pre.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - TrustComponent
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-02-09 00:00:00.000000000 Z
11
+ date: 2026-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -46,9 +46,9 @@ executables: []
46
46
  extensions: []
47
47
  extra_rdoc_files: []
48
48
  files:
49
- - lib/trustcaptcha/captcha_manager.rb
50
49
  - lib/trustcaptcha/model/verification_result.rb
51
50
  - lib/trustcaptcha/model/verification_token.rb
51
+ - lib/trustcaptcha/trust_captcha.rb
52
52
  homepage: https://www.trustcomponent.com/en/products/captcha/integrations/ruby-captcha
53
53
  licenses:
54
54
  - Apache-2.0
@@ -65,9 +65,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
65
  version: '0'
66
66
  required_rubygems_version: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ">="
68
+ - - ">"
69
69
  - !ruby/object:Gem::Version
70
- version: '0'
70
+ version: 1.3.1
71
71
  requirements: []
72
72
  rubygems_version: 3.3.7
73
73
  signing_key:
@@ -1,56 +0,0 @@
1
- require 'net/http'
2
- require 'uri'
3
- require 'json'
4
- require_relative 'model/verification_token'
5
- require_relative 'model/verification_result'
6
-
7
- class CaptchaManager
8
-
9
- class SecretKeyInvalidException < StandardError; end
10
- class VerificationTokenInvalidException < StandardError; end
11
- class VerificationNotFoundException < StandardError; end
12
- class VerificationNotFinishedException < StandardError; end
13
-
14
- def self.get_verification_result(secret_key, base64_verification_token)
15
- verification_token = get_verification_token(base64_verification_token)
16
- fetch_verification_result(verification_token, secret_key)
17
- end
18
-
19
- private
20
-
21
- def self.get_verification_token(base64_verification_token)
22
- VerificationToken.from_base64(base64_verification_token)
23
- rescue StandardError => e
24
- raise VerificationTokenInvalidException, "Invalid verification token: #{e.message}"
25
- end
26
-
27
- def self.fetch_verification_result(verification_token, access_token)
28
- url = URI("https://api.trustcomponent.com/verifications/#{verification_token.verification_id}/assessments")
29
- headers = {
30
- "tc-authorization" => access_token,
31
- "tc-library-language" => "ruby",
32
- "tc-library-version" => "2.0"
33
- }
34
-
35
- http = Net::HTTP.new(url.host, url.port)
36
- http.use_ssl = true
37
- http.open_timeout = 3
38
- http.read_timeout = 5
39
-
40
- request = Net::HTTP::Get.new(url.request_uri, headers)
41
- response = http.request(request)
42
-
43
- case response.code.to_i
44
- when 403
45
- raise SecretKeyInvalidException, "Secret key is invalid"
46
- when 404
47
- raise VerificationNotFoundException, "Verification not found"
48
- when 423
49
- raise VerificationNotFinishedException, "Verification not finished"
50
- else
51
- raise "Failed to retrieve verification result: HTTP #{response.code}" unless response.is_a?(Net::HTTPSuccess)
52
- end
53
-
54
- VerificationResult.from_json(response.body)
55
- end
56
- end