vonage 7.25.0 → 7.26.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: 508c457f8278aae1d8cc3951a8b4c38423ab63307917c4bbc09960f45cbafa9f
4
- data.tar.gz: '00329df94f3ab44d6ab8d2552931438358f92ad59c121db87e1668bd1c336814'
3
+ metadata.gz: 5d3865caa299175327806358dbe9a66e59abefa41240a5d9a847e5e73a37ea50
4
+ data.tar.gz: 861a7ae004b3908083af43cae0809330732dc07aa7be22a3cc362dc8b538fdab
5
5
  SHA512:
6
- metadata.gz: 80d9743779edc4dca5c4c9babb6a8591d616e4ac2f393ca4932a5a8640574561b28c61c803dc7c397c99221f0a086bd4604f62e8b36b97c7fd2b7da85ddc88d0
7
- data.tar.gz: 40756daa0add532dead58f6d7d057e5bfc8f5d39a9bd84515bcdc08f9a6686eb983b6859f45b71fde9e11b8f474dbecb8a2973ff7270fe8256d813e281783341
6
+ metadata.gz: 336c7b033206cf204f41e513a2dc8a4c56b57750660e17b37aede3d200aedcced48352ab18ffa3d44f7924df34548f767f19c9189dc385d9f2557a584d399bd7
7
+ data.tar.gz: da28e64d300d4f70c789e670c10f60beb9fbb058c1da3af8f2f995a8a61541d5b73cea93342f0a5f3b1b0a620dbba5c277fe5b8617259a52446bbbbeed09042e
data/README.md CHANGED
@@ -528,6 +528,8 @@ The following is a list of Vonage APIs for which the Ruby SDK currently provides
528
528
  * [Conversation API](https://developer.vonage.com/en/conversation/overview)
529
529
  * [Meetings API](https://developer.vonage.com/en/meetings/overview)
530
530
  * [Messages API](https://developer.vonage.com/en/messages/overview)
531
+ * [Network Number Verification API](https://developer.vonage.com/en/number-verification/overview)
532
+ * [Network SIM Swap API](https://developer.vonage.com/en/sim-swap/overview)
531
533
  * [Number Insight API](https://developer.vonage.com/en/number-insight/overview)
532
534
  * [Numbers API](https://developer.vonage.com/en/numbers/overview)
533
535
  * [Proactive Connect API](https://developer.vonage.com/en/proactive-connect/overview) *
data/lib/vonage/basic.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Vonage
4
4
  class Basic < AbstractAuthentication
5
- def update(object)
5
+ def update(object, data)
6
6
  return unless object.is_a?(Net::HTTPRequest)
7
7
 
8
8
  object.basic_auth(@config.api_key, @config.api_secret)
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Vonage
5
5
  class BearerToken < AbstractAuthentication
6
- def update(object)
6
+ def update(object, data)
7
7
  return unless object.is_a?(Net::HTTPRequest)
8
8
 
9
9
  object['Authorization'] = 'Bearer ' + @config.token
data/lib/vonage/client.rb CHANGED
@@ -91,6 +91,20 @@ module Vonage
91
91
  @messaging ||= T.let(Messaging.new(config), T.nilable(Vonage::Messaging))
92
92
  end
93
93
 
94
+ # @return [NetworkNumberVerification]
95
+ #
96
+ sig { returns(T.nilable(Vonage::NetworkNumberVerification)) }
97
+ def network_number_verification
98
+ @network_number_verification ||= T.let(NetworkNumberVerification.new(config), T.nilable(Vonage::NetworkNumberVerification))
99
+ end
100
+
101
+ # @return [NetworkSIMSwap]
102
+ #
103
+ sig { returns(T.nilable(Vonage::NetworkSIMSwap)) }
104
+ def network_sim_swap
105
+ @network_sim_swap ||= T.let(NetworkSIMSwap.new(config), T.nilable(Vonage::NetworkSIMSwap))
106
+ end
107
+
94
108
  # @return [NumberInsight]
95
109
  #
96
110
  sig { returns(T.nilable(Vonage::NumberInsight)) }
@@ -5,9 +5,10 @@ module Vonage
5
5
  extend T::Sig
6
6
 
7
7
  sig { params(
8
- object: T.any(T::Hash[T.untyped, T.untyped], URI::HTTPS, Net::HTTP::Post, Net::HTTP::Get)
8
+ object: T.any(T::Hash[T.untyped, T.untyped], URI::HTTPS, Net::HTTP::Post, Net::HTTP::Get),
9
+ data: T.nilable(Hash)
9
10
  ).void }
10
- def update(object)
11
+ def update(object, data)
11
12
  return unless object.is_a?(Hash)
12
13
 
13
14
  @config = T.let(@config, T.nilable(Vonage::Config))
data/lib/vonage/keys.rb CHANGED
@@ -34,7 +34,10 @@ module Vonage
34
34
  'max_duration',
35
35
  'partial_captions',
36
36
  'status_callback_url',
37
- 'audio_rate'
37
+ 'audio_rate',
38
+ 'phone_number',
39
+ 'hashed_phone_number',
40
+ 'max_age'
38
41
  ]
39
42
  hash.transform_keys do |k|
40
43
  if exceptions.include?(k.to_s)
@@ -57,18 +57,15 @@ module Vonage
57
57
  Post = Net::HTTP::Post
58
58
  Delete = Net::HTTP::Delete
59
59
 
60
- def build_request(path:, type: Get, params: {})
60
+ def build_request(path:, type: Get, params: {}, auth_data: nil)
61
61
  authentication = self.class.authentication.new(@config)
62
- authentication.update(params)
62
+ authentication.update(params, auth_data)
63
63
 
64
64
  uri = URI("https://" + @host + path)
65
65
  unless type.const_get(:REQUEST_HAS_BODY) || params.empty?
66
66
  uri.query = Params.encode(params)
67
67
  end
68
68
 
69
- # Set BasicAuth if neeeded
70
- authentication.update(uri)
71
-
72
69
  # instantiate request
73
70
  request = type.new(uri)
74
71
 
@@ -80,8 +77,8 @@ module Vonage
80
77
  request["Accept"] = "application/json"
81
78
  self.class.request_headers.each { |key, value| request[key] = value }
82
79
 
83
- # Set BearerToken if needed
84
- authentication.update(request)
80
+ # Set Authorization header if needed
81
+ authentication.update(request, auth_data)
85
82
 
86
83
  # set body
87
84
  if type.const_get(:REQUEST_HAS_BODY)
@@ -106,7 +103,7 @@ module Vonage
106
103
  response
107
104
  end
108
105
 
109
- def request(path, params: nil, type: Get, response_class: Response, &block)
106
+ def request(path, params: nil, type: Get, response_class: Response, auth_data: nil, &block)
110
107
  auto_advance =
111
108
  (
112
109
  if !params.nil? && params.key?(:auto_advance)
@@ -120,7 +117,7 @@ module Vonage
120
117
  params.tap { |params| params.delete(:auto_advance) } if !params.nil? &&
121
118
  params.key?(:auto_advance)
122
119
 
123
- request = build_request(path: path, params: params || {}, type: type)
120
+ request = build_request(path: path, params: params || {}, type: type, auth_data: auth_data)
124
121
 
125
122
  response = make_request!(request, &block)
126
123
 
@@ -139,7 +136,7 @@ module Vonage
139
136
  end
140
137
  end
141
138
 
142
- def multipart_post_request(path, filepath:, file_name:, mime_type:, params: {}, override_uri: nil, no_auth: false, response_class: Response, &block)
139
+ def multipart_post_request(path, filepath:, file_name:, mime_type:, params: {}, override_uri: nil, no_auth: false, response_class: Response, auth_data: nil, &block)
143
140
  authentication = self.class.authentication.new(@config) unless no_auth
144
141
 
145
142
  uri = override_uri ? URI(override_uri) : URI('https://' + @host + path)
@@ -156,8 +153,8 @@ module Vonage
156
153
 
157
154
  request['User-Agent'] = UserAgent.string(@config.app_name, @config.app_version)
158
155
 
159
- # Set BearerToken if needed
160
- authentication.update(request) unless no_auth
156
+ # Set Authorization header if needed
157
+ authentication.update(request, auth_data) unless no_auth
161
158
 
162
159
  logger.log_request_info(request)
163
160
 
@@ -0,0 +1,39 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class NetworkAuthentication::ClientAuthentication < Namespace
6
+ extend T::Sig
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.host = :vonage_host
11
+
12
+ self.request_headers['Content-Type'] = 'application/x-www-form-urlencoded'
13
+
14
+ def token(oidc_auth_code:, redirect_uri:, **params)
15
+ request(
16
+ '/oauth2/token',
17
+ params: {
18
+ grant_type: 'authorization_code',
19
+ code: oidc_auth_code,
20
+ redirect_uri: redirect_uri
21
+ },
22
+ type: Post
23
+ ).access_token
24
+ end
25
+
26
+ def generate_oidc_uri(purpose:, api_scope:, login_hint:, redirect_uri:, state:)
27
+ scope = "openid%20dpv:#{purpose}%23#{api_scope}"
28
+ uri = "https://oidc.idp.vonage.com/oauth2/auth?" +
29
+ "client_id=#{@config.application_id}" +
30
+ "&response_type=code" +
31
+ "&scope=#{scope}" +
32
+ "&login_hint=#{login_hint}" +
33
+ "&redirect_uri=#{redirect_uri}" +
34
+ "&state=#{state}"
35
+
36
+ uri
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,47 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class NetworkAuthentication::ServerAuthentication < Namespace
6
+ extend T::Sig
7
+
8
+ self.authentication = BearerToken
9
+
10
+ self.host = :vonage_host
11
+
12
+ self.request_headers['Content-Type'] = 'application/x-www-form-urlencoded'
13
+
14
+ def token(purpose:, api_scope:, login_hint:, **params)
15
+ auth_req_id = bc_authorize(
16
+ purpose: purpose,
17
+ api_scope: api_scope,
18
+ login_hint: login_hint
19
+ ).auth_req_id
20
+
21
+ request_access_token(auth_req_id: auth_req_id).access_token
22
+ end
23
+
24
+ def bc_authorize(purpose:, api_scope:, login_hint:)
25
+ scope = "openid dpv:#{purpose}##{api_scope}"
26
+ request(
27
+ "/oauth2/bc-authorize",
28
+ params: {
29
+ scope: scope,
30
+ login_hint: login_hint
31
+ },
32
+ type: Post
33
+ )
34
+ end
35
+
36
+ def request_access_token(auth_req_id:)
37
+ request(
38
+ "/oauth2/token",
39
+ params: {
40
+ grant_type: 'urn:openid:params:grant-type:ciba',
41
+ auth_req_id: auth_req_id
42
+ },
43
+ type: Post
44
+ )
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,22 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Vonage
5
+ class NetworkAuthentication < AbstractAuthentication
6
+ def update(object, data)
7
+ return unless object.is_a?(Net::HTTPRequest)
8
+
9
+ token = self.public_send(data[:auth_flow]).token(**data)
10
+
11
+ object['Authorization'] = 'Bearer ' + token
12
+ end
13
+
14
+ def client_authentication
15
+ @client_authentication ||= ClientAuthentication.new(@config)
16
+ end
17
+
18
+ def server_authentication
19
+ @server_authentication ||= ServerAuthentication.new(@config)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,92 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+ require 'phonelib'
4
+
5
+ module Vonage
6
+ class NetworkNumberVerification < Namespace
7
+ extend T::Sig
8
+ include Keys
9
+
10
+ self.authentication = NetworkAuthentication
11
+
12
+ self.host = :vonage_host
13
+
14
+ self.request_body = JSON
15
+
16
+ # Verifies if the specified phone number (plain text or hashed format) matches the one that the user is currently using.
17
+ #
18
+ # @example
19
+ # response = client.network_number_verification.verify(
20
+ # phone_number: '+447900000000',
21
+ # auth_data: {
22
+ # oidc_auth_code: '0dadaeb4-7c79-4d39-b4b0-5a6cc08bf537',
23
+ # redirect_uri: 'https://example.com/callback'
24
+ # }
25
+ # )
26
+ #
27
+ # @param [required, String] :phone_number The phone number to check, in the E.164 format, prepended with a `+`.
28
+ #
29
+ # @param [required, Hash] :auth_data A hash of authentication data required for the client token request. Must contain the following keys:
30
+ # @option auth_data [required, String] :oidc_auth_code The OIDC auth code.
31
+ # @option auth_data [required, String] :redirect_uri The redirect URI.
32
+ # @see https://developer.vonage.com/en/getting-started-network/authentication#client-authentication-flow
33
+ #
34
+ # @return [Response]
35
+ #
36
+ # @see https://developer.vonage.com/en/api/camara/number-verification#verifyNumberVerification
37
+ #
38
+ sig { params(phone_number: String, auth_data: Hash).returns(Vonage::Response) }
39
+ def verify(phone_number:, auth_data:)
40
+ raise ArgumentError.new("`phone_number` must be in E.164 format") unless Phonelib.parse(phone_number).valid?
41
+ raise ArgumentError.new("`phone_number` must be prepended with a `+`") unless phone_number.start_with?('+')
42
+ raise ArgumentError.new("`auth_data` must contain key `:oidc_auth_code`") unless auth_data.has_key?(:oidc_auth_code)
43
+ raise ArgumentError.new("`auth_data[:oidc_auth_code]` must be a String") unless auth_data[:oidc_auth_code].is_a?(String)
44
+ raise ArgumentError.new("`auth_data` must contain key `:redirect_uri`") unless auth_data.has_key?(:redirect_uri)
45
+ raise ArgumentError.new("`auth_data[:redirect_uri]` must be a String") unless auth_data[:redirect_uri].is_a?(String)
46
+
47
+ params = {phone_number: phone_number}
48
+
49
+ request(
50
+ '/camara/number-verification/v031/verify',
51
+ params: camelcase(params),
52
+ type: Post,
53
+ auth_data: {
54
+ oidc_auth_code: auth_data[:oidc_auth_code],
55
+ redirect_uri: auth_data[:redirect_uri],
56
+ auth_flow: :client_authentication
57
+ }
58
+ )
59
+ end
60
+
61
+ # Creates a URL for a client-side OIDC request.
62
+ #
63
+ # @example
64
+ # response = client.network_number_verification.generate_oidc_uri(
65
+ # phone_number: '+447900000000',
66
+ # redirect_uri: 'https://example.com/callback'
67
+ # )
68
+ #
69
+ # @param [required, String] :phone_number The phone number that will be checked during the verification request.
70
+ #
71
+ # @param [required, String] :redirect_uri The URI that will receive the callback containing the OIDC auth code.
72
+ #
73
+ # @param [required, String] :state A string that you can use for tracking.
74
+ # Used to set a unique identifier for each access token you generate.
75
+ #
76
+ # @return [String]
77
+ #
78
+ # @see https://developer.vonage.com/en/getting-started-network/authentication#1-make-an-oidc-request
79
+ sig { params(phone_number: String, redirect_uri: String, state: String).returns(String) }
80
+ def generate_oidc_uri(phone_number:, redirect_uri:, state:)
81
+ params = {
82
+ purpose: 'FraudPreventionAndDetection',
83
+ api_scope: 'number-verification-verify-read',
84
+ login_hint: phone_number,
85
+ redirect_uri: redirect_uri,
86
+ state: state
87
+ }
88
+
89
+ Vonage::NetworkAuthentication::ClientAuthentication.new(@config).generate_oidc_uri(**params)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,84 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+ require 'phonelib'
4
+
5
+ module Vonage
6
+ class NetworkSIMSwap < Namespace
7
+ extend T::Sig
8
+ include Keys
9
+
10
+ self.authentication = NetworkAuthentication
11
+
12
+ self.host = :vonage_host
13
+
14
+ self.request_body = JSON
15
+
16
+ # Check if SIM swap has been performed during a past period.
17
+ #
18
+ # @example
19
+ # response = client.network_sim_swap.check(phone_number: '+447900000000')
20
+ #
21
+ # @param [required, String] :phone_number The phone number to check, in the E.164 format, prepended with a `+`.
22
+ #
23
+ # @param [optional, Integer] :max_age Period in hours to be checked for SIM swap
24
+ #
25
+ # @return [Response]
26
+ #
27
+ # @see https://developer.vonage.com/en/api/camara/sim-swap#checkSimSwap
28
+ #
29
+ sig { params(phone_number: String, max_age: T.nilable(Integer)).returns(Vonage::Response) }
30
+ def check(phone_number:, max_age: nil)
31
+ raise ArgumentError.new("`phone_number` must be in E.164 format") unless Phonelib.parse(phone_number).valid?
32
+ raise ArgumentError.new("`phone_number` must be prepended with a `+`") unless phone_number.start_with?('+')
33
+ if max_age
34
+ raise ArgumentError.new("`max_age` must between 1 and 2400") unless max_age.between?(1, 2400)
35
+ end
36
+
37
+ params = {phone_number: phone_number}
38
+ params[:max_age] = max_age if max_age
39
+
40
+ request(
41
+ '/camara/sim-swap/v040/check',
42
+ params: camelcase(params),
43
+ type: Post,
44
+ auth_data: {
45
+ login_hint: phone_number,
46
+ purpose: 'FraudPreventionAndDetection',
47
+ api_scope: 'check-sim-swap',
48
+ auth_flow: :server_authentication
49
+ }
50
+ )
51
+ end
52
+
53
+ # Get timestamp of last MSISDN <-> IMSI pairing change for a mobile user account provided with MSIDN.
54
+ #
55
+ # @example
56
+ # response = client.network_sim_swap.retrieve_date(phone_number: '+447900000000')
57
+ #
58
+ # @param [required, String] :phone_number The phone number to check, in the E.164 format, prepended with a `+`.
59
+ #
60
+ # @return [Response]
61
+ #
62
+ # @see https://developer.vonage.com/en/api/camara/sim-swap#retrieveSimSwapDate
63
+ #
64
+ sig { params(phone_number: String).returns(Vonage::Response) }
65
+ def retrieve_date(phone_number:)
66
+ raise ArgumentError.new("`phone_number` must be in E.164 format") unless Phonelib.parse(phone_number).valid?
67
+ raise ArgumentError.new("`phone_number` must be prepended with a `+`") unless phone_number.start_with?('+')
68
+
69
+ params = {phone_number: phone_number}
70
+
71
+ request(
72
+ '/camara/sim-swap/v040/retrieve-date',
73
+ params: camelcase(params),
74
+ type: Post,
75
+ auth_data: {
76
+ login_hint: phone_number,
77
+ purpose: 'FraudPreventionAndDetection',
78
+ api_scope: 'retrieve-sim-swap-date',
79
+ auth_flow: :server_authentication
80
+ }
81
+ )
82
+ end
83
+ end
84
+ end
@@ -5,7 +5,7 @@ module Vonage
5
5
  class Verify2::StartVerificationOptions
6
6
  VALID_OPTS = [:locale, :channel_timeout, :client_ref, :code_length, :code, :fraud_check].freeze
7
7
 
8
- MIN_CHANNEL_TIMEOUT, MAX_CHANNEL_TIMEOUT = [60, 900]
8
+ MIN_CHANNEL_TIMEOUT, MAX_CHANNEL_TIMEOUT = [15, 900]
9
9
 
10
10
  MIN_CODE_LENGTH, MAX_CODE_LENGTH = [4, 10]
11
11
 
@@ -22,6 +22,7 @@ module Vonage
22
22
  end
23
23
 
24
24
  def channel_timeout=(channel_timeout)
25
+ raise ArgumentError, "Invalid 'channel_timeout' #{channel_timeout}. Must be an integer" unless channel_timeout.is_a?(Integer)
25
26
  unless channel_timeout.between?(MIN_CHANNEL_TIMEOUT, MAX_CHANNEL_TIMEOUT)
26
27
  raise ArgumentError, "Invalid 'channel_timeout' #{channel_timeout}. Must be between #{MIN_CHANNEL_TIMEOUT} and #{MAX_CHANNEL_TIMEOUT} (inclusive)"
27
28
  end
@@ -1,5 +1,5 @@
1
1
  # typed: strong
2
2
 
3
3
  module Vonage
4
- VERSION = '7.25.0'
4
+ VERSION = '7.26.0'
5
5
  end
@@ -209,6 +209,7 @@ module Vonage
209
209
  }
210
210
 
211
211
  hash.merge!(headers: endpoint_attrs[:headers]) if endpoint_attrs[:headers]
212
+ hash.merge!(standardHeaders: endpoint_attrs[:standardHeaders]) if endpoint_attrs[:standardHeaders]
212
213
 
213
214
  hash
214
215
  end
data/lib/vonage/voice.rb CHANGED
@@ -18,6 +18,8 @@ module Vonage
18
18
  #
19
19
  # @option params [required, Array<Hash>] :to
20
20
  # Connect to a Phone (PSTN) number, SIP Endpoint, Websocket, or VBC extension.
21
+ # The `to` Hash can contain a number of different properties depending on the `type`.
22
+ # See the API reference for specific details.
21
23
  #
22
24
  # @option params [Hash] :from
23
25
  # Connect to a Phone (PSTN) number. Should not be set if **:random_from_number** is **true**
data/lib/vonage.rb CHANGED
@@ -15,6 +15,7 @@ module Vonage
15
15
  'jwt' => 'JWT',
16
16
  'sip' => 'SIP',
17
17
  'sms' => 'SMS',
18
+ 'network_sim_swap' => 'NetworkSIMSwap',
18
19
  'mms' => 'MMS',
19
20
  'tfa' => 'TFA',
20
21
  'version' => 'VERSION',
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vonage
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.25.0
4
+ version: 7.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vonage
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-19 00:00:00.000000000 Z
11
+ date: 2024-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: vonage-jwt
@@ -189,6 +189,11 @@ files:
189
189
  - lib/vonage/messaging/channels/whats_app.rb
190
190
  - lib/vonage/messaging/message.rb
191
191
  - lib/vonage/namespace.rb
192
+ - lib/vonage/network_authentication.rb
193
+ - lib/vonage/network_authentication/client_authentication.rb
194
+ - lib/vonage/network_authentication/server_authentication.rb
195
+ - lib/vonage/network_number_verification.rb
196
+ - lib/vonage/network_sim_swap.rb
192
197
  - lib/vonage/number_insight.rb
193
198
  - lib/vonage/number_insight_2.rb
194
199
  - lib/vonage/numbers.rb