authsignal-ruby 3.0.0 → 4.0.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: b0204e93c2f7fa2b3bf20379b5837243a62960ce0b35c39d69e41f6c98b02125
4
- data.tar.gz: 4624f0d600ac6377b4d2ef3945121e7a8dc628852786ca8ecccb2b6c7b589d07
3
+ metadata.gz: '05993f5ac8d8569efae1a1c17692b90216c135675c922a4ef727124ba4774b5c'
4
+ data.tar.gz: 7f1816f80f7bf7517fda22b2f5d2cc0ad9895431031b06e0dfdf52dc4065c355
5
5
  SHA512:
6
- metadata.gz: 6c9592f43a421e9bd5032b3d81aa44a10e30e03553e293667b5ac1ca7b196d4cad3a12e544e41f70392a54649ed584a8ef4a1a9259363e5de4a4104e50f20601
7
- data.tar.gz: 1409c27d455564263fb596e1ac920f5867540711ea07a8bd2b85a47a07c0843dded453c3648557e81ac8d6586539bb531d551c2d09c19178b728c6720d005944
6
+ metadata.gz: eb669c48e8fcb98f9241b0cde59c9aba13b4f1991f83f2e6ca0b127338af6d31c123cac2d3a9dec0cafc19142fb0fe9c5a212f792fb2c5655f22d13757f1dee6
7
+ data.tar.gz: 1e2622b946b9979010eb0f34a7de0b76eda3197242d441807b1bde5a038fe6cbd6a70a9e94ef54cdad4c23d1298f5d49f3f3a6ec2a11bd47a594775467c48342
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 (4.0.0)
5
5
  faraday (>= 2)
6
6
  faraday-retry (~> 2.2)
7
7
 
@@ -14,7 +14,7 @@ GEM
14
14
  crack (1.0.0)
15
15
  bigdecimal
16
16
  rexml
17
- diff-lcs (1.5.0)
17
+ diff-lcs (1.5.1)
18
18
  faraday (2.12.0)
19
19
  faraday-net_http (>= 2.0, < 3.4)
20
20
  json
@@ -29,21 +29,21 @@ GEM
29
29
  net-http (0.4.1)
30
30
  uri
31
31
  public_suffix (6.0.1)
32
- rake (13.0.6)
32
+ rake (13.2.1)
33
33
  rexml (3.3.8)
34
- rspec (3.11.0)
35
- rspec-core (~> 3.11.0)
36
- rspec-expectations (~> 3.11.0)
37
- rspec-mocks (~> 3.11.0)
38
- rspec-core (3.11.0)
39
- rspec-support (~> 3.11.0)
40
- rspec-expectations (3.11.0)
34
+ rspec (3.13.0)
35
+ rspec-core (~> 3.13.0)
36
+ rspec-expectations (~> 3.13.0)
37
+ rspec-mocks (~> 3.13.0)
38
+ rspec-core (3.13.2)
39
+ rspec-support (~> 3.13.0)
40
+ rspec-expectations (3.13.3)
41
41
  diff-lcs (>= 1.2.0, < 2.0)
42
- rspec-support (~> 3.11.0)
43
- rspec-mocks (3.11.1)
42
+ rspec-support (~> 3.13.0)
43
+ rspec-mocks (3.13.2)
44
44
  diff-lcs (>= 1.2.0, < 2.0)
45
- rspec-support (~> 3.11.0)
46
- rspec-support (3.11.0)
45
+ rspec-support (~> 3.13.0)
46
+ rspec-support (3.13.1)
47
47
  uri (0.13.1)
48
48
  webmock (3.24.0)
49
49
  addressable (>= 2.8.0)
@@ -51,6 +51,7 @@ GEM
51
51
  hashdiff (>= 0.4.0, < 2.0.0)
52
52
 
53
53
  PLATFORMS
54
+ arm64-darwin-24
54
55
  ruby
55
56
 
56
57
  DEPENDENCIES
@@ -60,4 +61,4 @@ DEPENDENCIES
60
61
  webmock (~> 3.14)
61
62
 
62
63
  BUNDLED WITH
63
- 2.3.21
64
+ 2.5.16
data/README.md CHANGED
@@ -63,6 +63,55 @@ 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
+
68
+ ```ruby
69
+ Authsignal.track user_id: 'AS_001', action: 'withdraw', idempotency_key: 'a_random_hash'
70
+
71
+ # returns:
72
+ # {
73
+ # success?: true,
74
+ # state: 'ALLOW',
75
+ # idempotency_key: 'a_random_hash',
76
+ # ... rest of payload ...
77
+ # }
78
+ ```
79
+
80
+ ### Response & Error handling
81
+
82
+ The Authsignal SDK offers two response formats. By default, its methods return the payload in hash format.
83
+
84
+ Example:
85
+
86
+ ```ruby
87
+ Authsignal.enroll_verified_authenticator user_id: 'AS_001',
88
+ authenticator: {
89
+ oob_channel: 'INVALID', email: 'joebloke@authsignal.com'
90
+ }
91
+
92
+ # returns:
93
+ # {
94
+ # success?: false,
95
+ # status: 400,
96
+ # error: 'invalid_request',
97
+ # error_description: '/body/oobChannel must be equal to one of the allowed values'
98
+ # }
99
+ ```
100
+
101
+ All methods have a bang (!) counterpart that raises an Authsignal::ApiError if the request fails.
102
+
103
+ Example:
104
+
105
+ ```ruby
106
+ Authsignal.enroll_verified_authenticator! user_id: 'AS_001',
107
+ authenticator: {
108
+ oob_channel: 'INVALID', email: 'joebloke@authsignal.com'
109
+ }
110
+
111
+ # raise:
112
+ # <Authsignal::ApiError: invalid_request status: 400, error: invalid_request, description: /body/oobChannel must be equal to one o...
113
+ ```
114
+
66
115
  ## Development
67
116
 
68
117
  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,11 @@ 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
+ body = { user_id: user_id, token: token, action: action }
68
69
 
69
- make_request(:post, path, body: { user_id: user_id, token: token })
70
+ make_request(:post, path, body: body)
70
71
  end
71
72
 
72
73
  def get_action(user_id, action, idempotency_key)
@@ -83,16 +84,12 @@ module Authsignal
83
84
  make_request(:post, "users/#{url_encode(user_id)}/authenticators", body: authenticator)
84
85
  end
85
86
 
86
- def delete_user_authenticator(user_id:, user_authenticator_id:)
87
+ def delete_authenticator(user_id:, user_authenticator_id:)
87
88
  make_request(:delete, "users/#{url_encode(user_id)}/authenticators/#{url_encode(user_authenticator_id)}")
88
89
  end
89
90
 
90
91
  private
91
92
 
92
- def make_request(method, path, body: nil, headers: nil)
93
- @client.public_send(method, path, body, headers)
94
- end
95
-
96
93
  def url_encode(s)
97
94
  ERB::Util.url_encode(s)
98
95
  end
@@ -108,5 +105,12 @@ module Authsignal
108
105
  def require_api_key
109
106
  Authsignal.configuration.api_secret_key || print_api_key_warning
110
107
  end
108
+
109
+ def make_request(method, path, body: nil, headers: nil)
110
+ if body.is_a?(Hash)
111
+ body = body.reject { |_, v| v.nil? }
112
+ end
113
+ @client.public_send(method, path, body, headers)
114
+ end
111
115
  end
112
116
  end
@@ -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 = "4.0.0"
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
 
@@ -52,8 +55,8 @@ module Authsignal
52
55
  handle_response(response)
53
56
  end
54
57
 
55
- def delete_user_authenticator(user_id:, user_authenticator_id: )
56
- response = Client.new.delete_user_authenticator(user_id: user_id, user_authenticator_id: user_authenticator_id)
58
+ def delete_authenticator(user_id:, user_authenticator_id: )
59
+ response = Client.new.delete_authenticator(user_id: user_id, user_authenticator_id: user_authenticator_id)
57
60
 
58
61
  handle_response(response)
59
62
  end
@@ -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: 4.0.0
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-25 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