authsignal-ruby 3.0.0 → 3.0.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: b0204e93c2f7fa2b3bf20379b5837243a62960ce0b35c39d69e41f6c98b02125
4
- data.tar.gz: 4624f0d600ac6377b4d2ef3945121e7a8dc628852786ca8ecccb2b6c7b589d07
3
+ metadata.gz: e2bf6c96e9f79775fa1d3db3deb5ec5258a8c651e1b4fb8c1c3740c3f5ebd5b6
4
+ data.tar.gz: 90124d4aa0b3111cd4b52424c78b16f208d4179991e8dcfc52f48fc735483bba
5
5
  SHA512:
6
- metadata.gz: 6c9592f43a421e9bd5032b3d81aa44a10e30e03553e293667b5ac1ca7b196d4cad3a12e544e41f70392a54649ed584a8ef4a1a9259363e5de4a4104e50f20601
7
- data.tar.gz: 1409c27d455564263fb596e1ac920f5867540711ea07a8bd2b85a47a07c0843dded453c3648557e81ac8d6586539bb531d551c2d09c19178b728c6720d005944
6
+ metadata.gz: 1cb34330978dc710806be016761805b82c7cc442ab58752baf33ff62bff64a4476c7f62fce114e10f3dae144c100ae4fe05d167cd66435d3d38fdcb3adb63612
7
+ data.tar.gz: 5dca5b72d6c09fa2bfe78768d451661f6bad5d1188257a6d7523f51f389956c51214af1250c2f318706274b080c9a9ada019ad2f5e246f0daface09e05351096
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- authsignal-ruby (3.0.0)
4
+ authsignal-ruby (3.0.1)
5
5
  faraday (>= 2)
6
6
  faraday-retry (~> 2.2)
7
7
 
data/README.md CHANGED
@@ -63,6 +63,52 @@ Authsignal's server side signal API has four main api calls `track`, `get_action
63
63
 
64
64
  For more details on these api calls, refer to our [official Ruby SDK docs](https://docs.authsignal.com/sdks/server/ruby#track).
65
65
 
66
+ Example:
67
+ ```ruby
68
+ Authsignal.track user_id: 'AS_001', action: 'withdraw', idempotency_key: 'a_random_hash'
69
+
70
+ # returns:
71
+ # {
72
+ # success?: true,
73
+ # state: 'ALLOW',
74
+ # idempotency_key: 'a_random_hash',
75
+ # ... rest of payload ...
76
+ # }
77
+ ```
78
+
79
+ ### Response & Error handling
80
+
81
+ Authsignal client come with 2 flavors of responses, by default calling the signal APIs will returns payload in hash.
82
+
83
+ Example:
84
+ ```ruby
85
+ Authsignal.enroll_verified_authenticator user_id: 'AS_001',
86
+ authenticator: {
87
+ oob_channel: 'INVALID', email: 'joebloke@authsignal.com'
88
+ }
89
+
90
+ # returns:
91
+ # {
92
+ # success?: false,
93
+ # status: 400,
94
+ # error: 'invalid_request',
95
+ # error_description: '/body/oobChannel must be equal to one of the allowed values'
96
+ # }
97
+ ```
98
+
99
+ All signal APIs come with a bang(`!`) counterpart, which will raise `Authsignal::ApiError` when the request is unsuccessful.
100
+
101
+
102
+ Example:
103
+ ```ruby
104
+ Authsignal.enroll_verified_authenticator! user_id: 'AS_001',
105
+ authenticator: {
106
+ oob_channel: 'INVALID', email: 'joebloke@authsignal.com'
107
+ }
108
+
109
+ # raise:
110
+ # <Authsignal::ApiError: invalid_request status: 400, error: invalid_request, description: /body/oobChannel must be equal to one o...
111
+ ```
66
112
  ## Development
67
113
 
68
114
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` or `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authsignal
4
+ class ApiError < StandardError
5
+ attr_reader :status, :error, :description
6
+
7
+ def initialize(message = "An unexpected API error occurred", status, error, description)
8
+ @status = status || 500
9
+ @error = error
10
+ @description = description
11
+
12
+ super(message)
13
+ end
14
+
15
+ def to_s
16
+ "#{super} status: #{status}, error: #{error}, description: #{description}"
17
+ end
18
+ end
19
+ end
@@ -63,10 +63,10 @@ module Authsignal
63
63
  make_request(:delete, "users/#{url_encode(user_id)}")
64
64
  end
65
65
 
66
- def validate_challenge(user_id: nil, token:)
66
+ def validate_challenge(user_id: nil, token:, action: nil)
67
67
  path = "validate"
68
68
 
69
- make_request(:post, path, body: { user_id: user_id, token: token })
69
+ make_request(:post, path, body: { user_id: user_id, token: token, action: action })
70
70
  end
71
71
 
72
72
  def get_action(user_id, action, idempotency_key)
@@ -9,6 +9,7 @@ module Authsignal
9
9
  # Otherwise, we can safe guard with: env.response_headers['content-type'] =~ /application\/json/
10
10
  parsed_body = JSON.parse(env.body)
11
11
  if parsed_body.is_a?(Hash)
12
+ parsed_body.delete("actionCode") # Remove deprecated actionCode from response
12
13
  env.body = transform_to_snake_case(parsed_body)
13
14
  end
14
15
  rescue JSON::ParserError
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Authsignal
4
- VERSION = "3.0.0"
4
+ VERSION = "3.0.1"
5
5
  end
data/lib/authsignal.rb CHANGED
@@ -3,10 +3,13 @@ require "faraday/retry"
3
3
  require "authsignal/version"
4
4
  require "authsignal/client"
5
5
  require "authsignal/configuration"
6
+ require "authsignal/api_error"
6
7
  require "authsignal/middleware/json_response"
7
8
  require "authsignal/middleware/json_request"
8
9
 
9
10
  module Authsignal
11
+ NON_API_METHODS = [:setup, :configuration, :default_configuration]
12
+
10
13
  class << self
11
14
  attr_writer :configuration
12
15
 
@@ -66,8 +69,8 @@ module Authsignal
66
69
  handle_response(response)
67
70
  end
68
71
 
69
- def validate_challenge(token:, user_id: nil)
70
- response = Client.new.validate_challenge(user_id: user_id, token: token)
72
+ def validate_challenge(token:, user_id: nil, action: nil)
73
+ response = Client.new.validate_challenge(user_id: user_id, token: token, action: action)
71
74
 
72
75
  handle_response(response)
73
76
  end
@@ -76,18 +79,35 @@ module Authsignal
76
79
 
77
80
  def handle_response(response)
78
81
  if response.success?
79
- response.body
82
+ handle_success_response(response)
80
83
  else
81
84
  handle_error_response(response)
82
85
  end
83
86
  end
84
87
 
88
+ def handle_success_response(response)
89
+ response.body.merge(success?: true)
90
+ end
91
+
85
92
  def handle_error_response(response)
86
93
  case response.body
87
94
  when Hash
88
- response.body.merge({ status: response.status })
95
+ response.body.merge(status: response.status, success?: false)
89
96
  else
90
- { status: response.status }
97
+ { status: response&.status || 500, success?: false }
98
+ end
99
+ end
100
+ end
101
+
102
+ methods = Authsignal.singleton_class.public_instance_methods(false)
103
+ (methods - NON_API_METHODS).each do |method|
104
+ define_singleton_method("#{method}!") do |*args, **kwargs|
105
+ send(method, *args, **kwargs).tap do |response|
106
+ status = response[:status]
107
+ err = response[:error]
108
+ desc = response[:error_description]
109
+
110
+ raise ApiError.new(err, status, err, desc) unless response[:success?]
91
111
  end
92
112
  end
93
113
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authsignal-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - justinsoong
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-14 00:00:00.000000000 Z
11
+ date: 2024-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -100,6 +100,7 @@ files:
100
100
  - bin/console
101
101
  - bin/setup
102
102
  - lib/authsignal.rb
103
+ - lib/authsignal/api_error.rb
103
104
  - lib/authsignal/client.rb
104
105
  - lib/authsignal/configuration.rb
105
106
  - lib/authsignal/middleware/json_request.rb