vonage 7.25.0 → 7.26.0

Sign up to get free protection for your applications and to get access to all the features.
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