authy 2.7.5 → 3.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.
@@ -6,11 +6,9 @@ require 'json'
6
6
 
7
7
  require 'authy/version'
8
8
  require 'authy/url_helpers'
9
- require 'authy/core_ext'
10
9
  require 'authy/response'
11
10
  require 'authy/models/user'
12
11
  require 'authy/config'
13
12
  require 'authy/api'
14
- require 'authy/phone_intelligence'
15
13
  require 'authy/phone_verification'
16
14
  require 'authy/onetouch'
@@ -1,12 +1,6 @@
1
- require 'logger'
1
+ require "logger"
2
2
 
3
3
  module Authy
4
-
5
- AUTHY_LOGGER = Logger.new(STDOUT)
6
- #
7
- # Authy.api_key = 'foo'
8
- # Authy.api_uri = 'http://test-authy-api.heroku.com/'
9
- #
10
4
  class API
11
5
  MIN_TOKEN_SIZE = 6
12
6
  MAX_TOKEN_SIZE = 12
@@ -25,7 +19,7 @@ module Authy
25
19
  }
26
20
 
27
21
  url = "#{Authy.api_uri}/protected/json/users/new"
28
- response = http_client.post(url, :body => escape_query(params), :header => default_header(api_key: api_key))
22
+ response = http_client.post(url, :body => escape_query(params), :header => default_header(params: { api_key: api_key }))
29
23
 
30
24
  Authy::User.new(response)
31
25
  end
@@ -36,19 +30,18 @@ module Authy
36
30
  # :force (true|false) force to check even if the cellphone is not confirmed
37
31
  #
38
32
  def self.verify(params)
39
- token = params.delete(:token) || params.delete('token')
40
- user_id = params.delete(:id) || params.delete('id')
33
+ token = params.delete(:token) || params.delete("token")
34
+ user_id = params.delete(:id) || params.delete("id")
41
35
 
42
- return invalid_response('Token format is invalid') unless token_is_safe?(token)
43
- return invalid_response('User id is invalid') unless is_digit?(user_id)
36
+ return invalid_response("Token format is invalid") unless token_is_safe?(token)
37
+ return invalid_response("User id is invalid") unless is_digit?(user_id)
44
38
 
45
- params[:force] = true if params[:force].nil? && params['force'].nil?
39
+ params[:force] = true if params[:force].nil? && params["force"].nil?
46
40
 
47
41
  response = get_request("protected/json/verify/:token/:user_id", params.merge({
48
- "token" => token,
49
- "user_id" => user_id
50
- })
51
- )
42
+ "token" => token,
43
+ "user_id" => user_id
44
+ }))
52
45
 
53
46
  return verify_response(response) if response.ok?
54
47
  return response
@@ -58,7 +51,7 @@ module Authy
58
51
  # :id user id
59
52
  # :force force sms
60
53
  def self.request_sms(params)
61
- user_id = params.delete(:id) || params.delete('id')
54
+ user_id = params.delete(:id) || params.delete("id")
62
55
 
63
56
  get_request("protected/json/sms/:user_id", params.merge({"user_id" => user_id}))
64
57
  end
@@ -68,14 +61,14 @@ module Authy
68
61
  # :qr_size qr size
69
62
  # :qr_label context for qr code
70
63
  def self.request_qr_code(params)
71
- user_id = params.delete(:id) || params.delete('id')
72
- qr_size = params.delete(:qr_size) || params.delete('qr_size') || 300
73
- qr_label = params.delete(:qr_label) || params.delete('qr_label') || ""
64
+ user_id = params.delete(:id) || params.delete("id")
65
+ qr_size = params.delete(:qr_size) || params.delete("qr_size") || 300
66
+ qr_label = params.delete(:qr_label) || params.delete("qr_label") || ""
74
67
 
75
- return invalid_response('User id is invalid') unless is_digit?(user_id)
76
- return invalid_response('Qr image size is invalid') unless is_digit?(qr_size)
68
+ return invalid_response("User id is invalid") unless is_digit?(user_id)
69
+ return invalid_response("Qr image size is invalid") unless is_digit?(qr_size)
77
70
 
78
- response = post_request("protected/json/users/:user_id/secret" ,params.merge({
71
+ response = post_request("protected/json/users/:user_id/secret", params.merge({
79
72
  "user_id" => user_id,
80
73
  "qr_size" => qr_size,
81
74
  "label" => qr_label
@@ -86,19 +79,38 @@ module Authy
86
79
  # :id user id
87
80
  # :force force phone_call
88
81
  def self.request_phone_call(params)
89
- user_id = params.delete(:id) || params.delete('id')
82
+ user_id = params.delete(:id) || params.delete("id")
90
83
 
91
84
  get_request("protected/json/call/:user_id", params.merge({"user_id" => user_id}))
92
85
  end
93
86
 
94
87
  # options:
95
88
  # :id user id
96
- def self.delete_user(params)
89
+ def self.request_email(params)
90
+ user_id = params.delete(:id) || params.delete('id')
91
+
92
+ post_request("protected/json/email/:user_id", params.merge({"user_id" => user_id}))
93
+ end
94
+
95
+ # options:
96
+ # :id user id
97
+ # :email user's new email
98
+ def self.update_user(params)
97
99
  user_id = params.delete(:id) || params.delete('id')
98
100
 
99
- post_request("protected/json/users/delete/:user_id", params.merge({"user_id" =>user_id}))
101
+ post_request("protected/json/users/:user_id/update", params.merge({"user_id" => user_id}))
100
102
  end
101
103
 
104
+ # options:
105
+ # :id user id
106
+ def self.delete_user(params)
107
+ user_id = params.delete(:id) || params.delete("id")
108
+
109
+ post_request("protected/json/users/delete/:user_id", params.merge({"user_id" => user_id}))
110
+ end
111
+
112
+ # options:
113
+ # :id user id
102
114
  def self.user_status(params)
103
115
  user_id = params.delete(:id) || params.delete("id")
104
116
  get_request("protected/json/users/:user_id/status", params.merge({"user_id" => user_id}))
@@ -113,12 +125,12 @@ module Authy
113
125
  state, error = validate_for_url(uri_params, params)
114
126
 
115
127
  response = if state
116
- url = "#{Authy.api_uri}/#{eval_uri(uri, params)}"
117
- params = clean_uri_params(uri_params, params)
118
- http_client.post(url, :body => escape_query(params), header: header_)
119
- else
120
- build_error_response(error)
121
- end
128
+ url = "#{Authy.api_uri}/#{eval_uri(uri, params)}"
129
+ params = clean_uri_params(uri_params, params)
130
+ http_client.post(url, :body => escape_query(params), header: header_)
131
+ else
132
+ build_error_response(error)
133
+ end
122
134
  Authy::Response.new(response)
123
135
  end
124
136
 
@@ -128,24 +140,24 @@ module Authy
128
140
  uri_params = keys_to_verify(uri, params)
129
141
  state, error = validate_for_url(uri_params, params)
130
142
  response = if state
131
- url = "#{Authy.api_uri}/#{eval_uri(uri, params)}"
132
- params = clean_uri_params(uri_params, params)
133
- http_client.get(url, params, header_)
134
- else
135
- build_error_response(error)
136
- end
143
+ url = "#{Authy.api_uri}/#{eval_uri(uri, params)}"
144
+ params = clean_uri_params(uri_params, params)
145
+ http_client.get(url, params, header_)
146
+ else
147
+ build_error_response(error)
148
+ end
137
149
  Authy::Response.new(response)
138
150
  end
139
151
 
140
152
  def self.build_error_response(error = "blank uri param found")
141
153
  OpenStruct.new({
142
- 'status' => 400,
143
- 'body' => {
144
- 'success' => false,
145
- 'message' => error,
146
- 'errors' => {
147
- 'message' => error
148
- }
154
+ "status" => 400,
155
+ "body" => {
156
+ "success" => false,
157
+ "message" => error,
158
+ "errors" => {
159
+ "message" => error,
160
+ },
149
161
  }.to_json
150
162
  })
151
163
  end
@@ -158,32 +170,26 @@ module Authy
158
170
  !!(/^\d+$/.match str.to_s)
159
171
  end
160
172
 
161
- def self.invalid_response(str="Invalid resonse")
173
+ def self.invalid_response(str = "Invalid resonse")
162
174
  response = build_error_response(str)
163
175
  return Authy::Response.new(response)
164
176
  end
165
177
 
166
178
  def self.verify_response(response)
167
- return response if response['token'] == 'is valid'
168
- response = build_error_response('Token is invalid')
179
+ return response if response["token"] == "is valid"
180
+ response = build_error_response("Token is invalid")
169
181
  return Authy::Response.new(response)
170
182
  end
171
183
 
172
- def self.default_header(api_key: nil, params: {})
184
+ def self.default_header(params: {})
185
+ api_key = params.delete(:api_key) || params.delete("api_key")
186
+
173
187
  header = {
174
188
  "X-Authy-API-Key" => api_key || Authy.api_key,
175
189
  "User-Agent" => Authy.user_agent
176
190
  }
177
191
 
178
- api_key_ = params.delete(:api_key) || params.delete("api_key")
179
-
180
- if api_key_ && api_key_.strip != ""
181
- AUTHY_LOGGER.warn("[DEPRECATED]: The Authy API key should not be sent as a parameter. Please send the HTTP header 'X-Authy-API-Key' instead.")
182
- header["X-Authy-API-Key"] = api_key_
183
- end
184
-
185
192
  return header
186
193
  end
187
-
188
194
  end
189
195
  end
@@ -23,7 +23,7 @@ module Authy
23
23
  begin
24
24
  self.clean_hash!(details)
25
25
  self.clean_hash!(hidden_details)
26
- self.clean_logos!(logos)
26
+ logos = self.clean_logos!(logos)
27
27
  rescue => e
28
28
  return invalid_response("Invalid parameters: #{e.message}")
29
29
  end
@@ -6,8 +6,11 @@ module Authy
6
6
  # :phone_number The persons phone number.
7
7
  # :custom_code Pass along any generated custom code.
8
8
  # :custom_message Custom Message.
9
+ # :code_length Length of code to be sent(4-10).
10
+ # :locale The language of the message received by user.
9
11
  def self.start(params)
10
- params[:via] = "sms" unless %w(sms, call).include?(params[:via])
12
+ warn "Authy Phone Verification has been superseded by the Twilio Verify API. Check https://twil.io/verify-start-ruby to see how to start a verification with the Twilio Verify API."
13
+ params[:via] = "sms" unless %w(sms call).include?(params[:via])
11
14
 
12
15
  post_request("protected/json/phones/verification/start", params)
13
16
  end
@@ -17,8 +20,8 @@ module Authy
17
20
  # :phone_number The persons phone number.
18
21
  # :verification_code The verification code entered by the user.
19
22
  def self.check(params)
23
+ warn "Authy Phone Verification has been superseded by the Twilio Verify API. Check https://twil.io/verify-check-ruby to see how to check a verification the Twilio Verify API."
20
24
  get_request("protected/json/phones/verification/check", params)
21
25
  end
22
-
23
26
  end
24
27
  end
@@ -30,10 +30,6 @@ module Authy
30
30
  [ true, ""]
31
31
  end
32
32
 
33
- def escape_for_url(field)
34
- URI.escape(field.to_s.strip, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
35
- end
36
-
37
33
  def to_param(left, right)
38
34
  HTTP::Message.escape(left) + '=' + HTTP::Message.escape(right.to_s)
39
35
  end
@@ -1,3 +1,3 @@
1
1
  module Authy
2
- VERSION = "2.7.5"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -1,9 +1,17 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
+
3
+ class Utils
4
+ include Authy::URL
5
+ end
2
6
 
3
7
  describe "Authy::API" do
8
+ let(:headers) { { "X-Authy-API-Key" => Authy.api_key, "User-Agent" => "AuthyRuby/#{Authy::VERSION} (#{RUBY_PLATFORM}, Ruby #{RUBY_VERSION})" } }
9
+ let(:user_id) { 81547 }
10
+ let(:invalid_api_key) { "invalid_api_key" }
11
+
4
12
  describe "request headers" do
5
13
  it "contains api key and user agent in header" do
6
- expect_any_instance_of(HTTPClient).to receive(:request).twice.with(any_args, hash_including(header: { "X-Authy-API-Key" => Authy.api_key, "User-Agent" => "AuthyRuby/#{Authy::VERSION} (#{RUBY_PLATFORM}, Ruby #{RUBY_VERSION})" }) ) { double(ok?: true, body: "", status: 200) }
14
+ expect_any_instance_of(HTTPClient).to receive(:request).twice.with(any_args, hash_including(header: headers)) { double(ok?: true, body: "", status: 200) }
7
15
 
8
16
  url = "protected/json/foo/2"
9
17
  Authy::API.get_request(url, {})
@@ -12,50 +20,130 @@ describe "Authy::API" do
12
20
  end
13
21
 
14
22
  describe "Registering users" do
15
- it "should find or create a user" do
16
- user = Authy::API.register_user(
23
+ let(:register_user_url) { "#{Authy.api_uri}/protected/json/users/new" }
24
+
25
+ it "should register a user successfully" do
26
+ user_attributes = {
17
27
  email: generate_email,
18
28
  cellphone: generate_cellphone,
19
29
  country_code: 1
20
- )
30
+ }
31
+ response_json = {
32
+ "message" => "User created successfully.",
33
+ "user" => { "id" => user_id },
34
+ "success" => true
35
+ }.to_json
36
+ expect(Authy::API.http_client).to receive(:request)
37
+ .once
38
+ .with(:post, register_user_url, {
39
+ :body => Utils.escape_query(
40
+ :user => user_attributes,
41
+ :send_install_link_via_sms => true
42
+ ),
43
+ :header => headers
44
+ })
45
+ .and_return(double(:status => 200, :body => response_json))
46
+
47
+ user = Authy::API.register_user(user_attributes)
21
48
 
22
49
  expect(user).to be_kind_of(Authy::Response)
23
50
  expect(user).to be_kind_of(Authy::User)
24
51
  expect(user).to_not be_nil
25
52
  expect(user.id).to_not be_nil
26
- expect(user.id).to be_kind_of(Integer)
53
+ expect(user.id).to be(user_id)
27
54
  end
28
55
 
29
56
  it "should return the error messages as a hash" do
30
- user = Authy::API.register_user(
57
+ user_attributes = {
31
58
  email: generate_email,
32
59
  cellphone: "abc-1234",
33
60
  country_code: 1
34
- )
61
+ }
62
+ response_json = {
63
+ "cellphone" => "is invalid",
64
+ "message" => "User was not valid",
65
+ "success" => false,
66
+ "errors" => {
67
+ "cellphone" => "is invalid",
68
+ "message" => "User was not valid"
69
+ },
70
+ "error_code" => "60027"
71
+ }.to_json
72
+
73
+ expect(Authy::API.http_client).to receive(:request)
74
+ .once
75
+ .with(:post, register_user_url, {
76
+ :body => Utils.escape_query(
77
+ :user => user_attributes,
78
+ :send_install_link_via_sms => true
79
+ ),
80
+ :header => headers
81
+ })
82
+ .and_return(double(:status => 400, :body => response_json))
83
+
84
+ user = Authy::API.register_user(user_attributes)
35
85
 
36
86
  expect(user.errors).to be_kind_of(Hash)
37
- expect(user.errors['cellphone']).to include 'is invalid'
87
+ expect(user.errors["cellphone"]).to include "is invalid"
38
88
  end
39
89
 
40
90
  it "should allow to override the API key" do
41
- user = Authy::API.register_user(
91
+ response_json = {
92
+ "error_code" => "60001",
93
+ "message" => "Invalid API key",
94
+ "errors" => {"message" => "Invalid API key"},
95
+ "success" => false
96
+ }.to_json
97
+ user_attributes = {
42
98
  email: generate_email,
43
99
  cellphone: generate_cellphone,
44
100
  country_code: 1,
45
- api_key: "invalid_api_key"
46
- )
101
+ api_key: invalid_api_key
102
+ }
103
+
104
+ headers["X-Authy-API-Key"] = invalid_api_key
105
+
106
+ expect(Authy::API.http_client).to receive(:request)
107
+ .once
108
+ .with(:post, register_user_url, {
109
+ :body => Utils.escape_query(
110
+ :user => user_attributes.reject { |k,v| k === :api_key },
111
+ :send_install_link_via_sms => true
112
+ ),
113
+ :header => headers
114
+ })
115
+ .and_return(double(:status => 401, :body => response_json))
116
+
117
+ user = Authy::API.register_user(user_attributes)
47
118
 
48
119
  expect(user).to_not be_ok
49
- expect(user.errors['message']).to match(/invalid api key/i)
120
+ expect(user.errors["message"]).to match(/invalid api key/i)
50
121
  end
51
122
 
52
123
  it "should allow overriding send_install_link_via_sms default" do
53
- user = Authy::API.register_user(
124
+ response_json = {
125
+ "message" => "User created successfully.",
126
+ "user" => { "id" => user_id },
127
+ "success" => true
128
+ }.to_json
129
+ user_attributes = {
54
130
  email: generate_email,
55
131
  cellphone: generate_cellphone,
56
132
  country_code: 1,
57
- send_install_link_via_sms: false # Default is true. See http://docs.authy.com/totp.html#totp-api
58
- )
133
+ send_install_link_via_sms: false
134
+ }
135
+ expect(Authy::API.http_client).to receive(:request)
136
+ .once
137
+ .with(:post, register_user_url, {
138
+ :body => Utils.escape_query(
139
+ :user => user_attributes.reject { |k,v| k === :send_install_link_via_sms },
140
+ :send_install_link_via_sms => false
141
+ ),
142
+ :header => headers
143
+ })
144
+ .and_return(double(:status => 200, :body => response_json))
145
+
146
+ user = Authy::API.register_user(user_attributes)
59
147
 
60
148
  expect(user).to be_kind_of(Authy::Response)
61
149
  expect(user).to be_kind_of(Authy::User)
@@ -63,90 +151,98 @@ describe "Authy::API" do
63
151
  expect(user.id).to_not be_nil
64
152
  expect(user.id).to be_kind_of(Integer)
65
153
  end
66
-
67
154
  end
68
155
 
69
- describe "verificating tokens" do
70
- before do
71
- @email = generate_email
72
- @cellphone = generate_cellphone
73
- @user = Authy::API.register_user(
74
- email: @email,
75
- cellphone: @cellphone,
76
- country_code: 1
77
- )
78
- expect(@user).to be_ok
79
- end
156
+ describe "verifying tokens" do
157
+ let(:token) { "123456" }
158
+ let(:verify_url) { "#{Authy.api_uri}/protected/json/verify/#{token}/#{user_id}" }
80
159
 
81
- it "should fail to validate a given token if the user is not registered" do
82
- response = Authy::API.verify(token: 'invalid_token', id: @user.id)
160
+ it "should fail to validate a given token if the token is the wrong format" do
161
+ expect(Authy::API.http_client).to receive(:request).never
162
+ response = Authy::API.verify(token: "invalid_token", id: user_id)
83
163
 
84
164
  expect(response).to be_kind_of(Authy::Response)
85
165
  expect(response.ok?).to be_falsey
86
- expect(response.errors['message']).to include 'Token format is invalid'
166
+ expect(response.errors["message"]).to include "Token format is invalid"
87
167
  end
88
168
 
89
169
  it "should allow to override the API key" do
90
- response = Authy::API.verify(token: '123456', id: @user['id'], api_key: "invalid_api_key")
170
+ response_json = {
171
+ "error_code" => "60001",
172
+ "message" => "Invalid API key",
173
+ "errors" => {"message" => "Invalid API key"},
174
+ "success" => false
175
+ }.to_json
176
+ headers["X-Authy-API-Key"] = invalid_api_key
177
+ expect(Authy::API.http_client).to receive(:request)
178
+ .once
179
+ .with(:get, verify_url, {
180
+ :query => { :force => true },
181
+ :header => headers,
182
+ :follow_redirect => nil
183
+ })
184
+ .and_return(double(:status => 401, :body => response_json))
185
+
186
+ response = Authy::API.verify(token: "123456", id: user_id, api_key: invalid_api_key)
91
187
 
92
188
  expect(response).to_not be_ok
93
- expect(response.errors['message']).to match(/invalid api key/i)
189
+ expect(response.errors["message"]).to match(/invalid api key/i)
94
190
  end
95
191
 
96
192
  it "should escape the params" do
193
+ expect(Authy::API.http_client).to receive(:request).never
97
194
  expect do
98
- Authy::API.verify(token: '[=#%@$&#(!@);.,', id: @user['id'])
195
+ Authy::API.verify(token: "[=#%@$&#(!@);.,", id: user_id)
99
196
  end.to_not raise_error
100
197
  end
101
198
 
102
199
  it "should escape the params if have white spaces" do
200
+ expect(Authy::API.http_client).to receive(:request).never
103
201
  expect do
104
- Authy::API.verify(token: "token with space", id: @user['id'])
202
+ Authy::API.verify(token: "token with space", id: user_id)
105
203
  end.to_not raise_error
106
204
  end
107
205
 
108
206
  it "should fail if a param is missing" do
109
- response = Authy::API.verify(id: @user['id'])
207
+ expect(Authy::API.http_client).to receive(:request).never
208
+ response = Authy::API.verify(id: user_id)
110
209
  expect(response).to be_kind_of(Authy::Response)
111
210
  expect(response).to_not be_ok
112
- expect(response["message"]).to include('Token format is invalid')
211
+ expect(response["message"]).to include("Token format is invalid")
113
212
  end
114
213
 
115
- it 'fails when token format is invalid' do
116
- response = Authy::API.verify(token: '0000', id: @user.id)
214
+ it "fails when token format is invalid" do
215
+ expect(Authy::API.http_client).to receive(:request).never
216
+ response = Authy::API.verify(token: "0000", id: user_id)
117
217
 
118
218
  expect(response.ok?).to be_falsey
119
219
  expect(response).to be_kind_of(Authy::Response)
120
- expect(response.errors['message']).to eq 'Token format is invalid'
220
+ expect(response.errors["message"]).to eq "Token format is invalid"
121
221
  end
122
222
  end
123
223
 
124
224
  describe "requesting qr code for other authenticator apps" do
125
- before do
126
- @user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
127
- expect(@user).to be_ok
128
- end
129
-
130
225
  it "should request qrcode" do
131
- url = "#{Authy.api_uri}/protected/json/users/#{Authy::API.escape_for_url(@user.id)}/secret"
132
- expect_any_instance_of(HTTPClient).to receive(:request).with(:post, url, body: "qr_size=300&label=example+app+name", header: {"X-Authy-API-Key" => Authy.api_key, "User-Agent" => "AuthyRuby/#{Authy::VERSION} (#{RUBY_PLATFORM}, Ruby #{RUBY_VERSION})"}) { double(ok?: true, body: "", status: 200) }
133
- response = Authy::API.send("request_qr_code", id: @user.id, qr_size: 300, qr_label: "example app name")
226
+ url = "#{Authy.api_uri}/protected/json/users/#{user_id}/secret"
227
+ expect_any_instance_of(HTTPClient).to receive(:request).with(:post, url, body: "qr_size=300&label=example+app+name", header: { "X-Authy-API-Key" => Authy.api_key, "User-Agent" => "AuthyRuby/#{Authy::VERSION} (#{RUBY_PLATFORM}, Ruby #{RUBY_VERSION})" }) { double(ok?: true, body: "", status: 200) }
228
+ response = Authy::API.send("request_qr_code", id: user_id, qr_size: 300, qr_label: "example app name")
134
229
  expect(response).to be_ok
135
230
  end
136
231
 
137
-
138
232
  context "user id is not a number" do
139
233
  it "should not be ok" do
234
+ expect(Authy::API.http_client).to receive(:request).never
140
235
  response = Authy::API.send("request_qr_code", id: "tony")
141
- expect(response.errors['message']).to eq "User id is invalid"
236
+ expect(response.errors["message"]).to eq "User id is invalid"
142
237
  expect(response).to_not be_ok
143
238
  end
144
239
  end
145
240
 
146
241
  context "qr size is not a number" do
147
242
  it "should return the right error" do
148
- response = Authy::API.send("request_qr_code", id: @user.id, qr_size: "notanumber")
149
- expect(response.errors['message']).to eq "Qr image size is invalid"
243
+ expect(Authy::API.http_client).to receive(:request).never
244
+ response = Authy::API.send("request_qr_code", id: user_id, qr_size: "notanumber")
245
+ expect(response.errors["message"]).to eq "Qr image size is invalid"
150
246
  expect(response).to_not be_ok
151
247
  end
152
248
  end
@@ -155,58 +251,212 @@ describe "Authy::API" do
155
251
  ["sms", "phone_call"].each do |kind|
156
252
  title = kind.upcase
157
253
  describe "Requesting #{title}" do
158
- before do
159
- @user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
160
- expect(@user).to be_ok
161
- end
254
+ let(:uri_param) { kind == "phone_call" ? "call" : kind }
255
+ let(:url) { "#{Authy.api_uri}/protected/json/#{uri_param}/#{user_id}" }
162
256
 
163
257
  it "should request a #{title} token" do
164
- uri_param = kind == "phone_call" ? "call" : kind
165
- url = "#{Authy.api_uri}/protected/json/#{uri_param}/#{Authy::API.escape_for_url(@user.id)}"
166
- expect_any_instance_of(HTTPClient).to receive(:request).with(:get, url, {query:{}, header:{ "X-Authy-API-Key" => Authy.api_key, "User-Agent" => "AuthyRuby/#{Authy::VERSION} (#{RUBY_PLATFORM}, Ruby #{RUBY_VERSION})" }, follow_redirect:nil}) { double(ok?: true, body: "", status: 200) }
167
- response = Authy::API.send("request_#{kind}", id: @user.id)
258
+ expect_any_instance_of(HTTPClient).to receive(:request).with(:get, url, { query: {}, header: { "X-Authy-API-Key" => Authy.api_key, "User-Agent" => "AuthyRuby/#{Authy::VERSION} (#{RUBY_PLATFORM}, Ruby #{RUBY_VERSION})" }, follow_redirect: nil }) { double(ok?: true, body: "", status: 200) }
259
+ response = Authy::API.send("request_#{kind}", id: user_id)
168
260
  expect(response).to be_ok
169
261
  end
170
262
 
171
263
  it "should allow to override the API key" do
172
- response = Authy::API.send("request_#{kind}", id: @user.id, api_key: "invalid_api_key")
264
+ response_json = {
265
+ "error_code" => "60001",
266
+ "message" => "Invalid API key",
267
+ "errors" => {"message" => "Invalid API key"},
268
+ "success" => false
269
+ }.to_json
270
+ headers["X-Authy-API-Key"] = invalid_api_key
271
+ expect(Authy::API.http_client).to receive(:request)
272
+ .once
273
+ .with(:get, url, {
274
+ :header => headers,
275
+ :query => {},
276
+ :follow_redirect => nil
277
+ })
278
+ .and_return(double(:status => 401, :body => response_json))
279
+ response = Authy::API.send("request_#{kind}", id: user_id, api_key: invalid_api_key)
173
280
  expect(response).to_not be_ok
174
- expect(response.errors['message']).to match(/invalid api key/i)
281
+ expect(response.errors["message"]).to match(/invalid api key/i)
175
282
  end
176
283
 
177
284
  it "should request a #{title} token using custom actions" do
178
- response = Authy::API.send("request_#{kind}", id: @user.id, action: "custom action?", action_message: "Action message $%^?@#")
285
+ response_json = {
286
+ :success => true
287
+ }.to_json
288
+ expect(Authy::API.http_client).to receive(:request)
289
+ .once
290
+ .with(:get, url, {
291
+ :header => headers,
292
+ :query => {
293
+ :action => "custom action?",
294
+ :action_message => "Action message $%^?@#"
295
+ },
296
+ :follow_redirect => nil
297
+ })
298
+ .and_return(double(:status => 200, :body => response_json))
299
+ response = Authy::API.send("request_#{kind}", id: user_id, action: "custom action?", action_message: "Action message $%^?@#")
179
300
  expect(response).to be_ok
180
301
  end
181
302
 
182
303
  context "user doesn't exist" do
183
304
  it "should not be ok" do
305
+ url = "#{Authy.api_uri}/protected/json/#{uri_param}/tony"
306
+ response_json = {
307
+ "message" => "User not found.",
308
+ "success" => false,
309
+ "errors" => { "message" => "User not found." },
310
+ "error_code" => "60026"
311
+ }.to_json
312
+ expect(Authy::API.http_client).to receive(:request)
313
+ .once
314
+ .with(:get, url, {
315
+ :header => headers,
316
+ :query => { },
317
+ :follow_redirect => nil
318
+ })
319
+ .and_return(double(:status => 404, :body => response_json))
184
320
  response = Authy::API.send("request_#{kind}", id: "tony")
185
- expect(response.errors['message']).to eq "User not found."
321
+ expect(response.errors["message"]).to eq "User not found."
186
322
  expect(response).to_not be_ok
187
323
  end
188
324
  end
189
325
  end
190
326
  end
191
327
 
192
- describe "delete users" do
328
+ describe "Requesting email" do
329
+ it "should request an email token" do
330
+ response_json = {
331
+ "success" => true,
332
+ "message" => "Email token was sent",
333
+ "email" => "recipient@foo.com",
334
+ "email_id" => "EMa364aa751cc280d8c22772307e2c5760"
335
+ }.to_json
336
+ url = "#{Authy.api_uri}/protected/json/email/#{user_id}"
337
+
338
+ expect(Authy::API.http_client).to receive(:request)
339
+ .once
340
+ .with(:post, url, body: "", header: headers)
341
+ .and_return(double(ok?: true, body: response_json, status: 200))
342
+ response = Authy::API.request_email(id: user_id)
343
+ expect(response).to be_ok
344
+ end
345
+
193
346
  context "user doesn't exist" do
194
347
  it "should not be ok" do
195
- response = Authy::API.delete_user(id: "tony")
348
+ url = "#{Authy.api_uri}/protected/json/email/tony"
349
+ response_json = {
350
+ "message" => "User not found.",
351
+ "success" => false,
352
+ "errors" => {
353
+ "message" => "User not found."
354
+ },
355
+ "error_code" => "60026"
356
+ }.to_json
357
+ expect(Authy::API.http_client).to receive(:request)
358
+ .once
359
+ .with(:post, url, {
360
+ :header => headers,
361
+ :body => ""
362
+ })
363
+ .and_return(double(:status => 404, :body => response_json))
364
+ response = Authy::API.request_email(id: "tony")
365
+ expect(response.errors['message']).to eq "User not found."
366
+ expect(response).to_not be_ok
367
+ end
368
+ end
369
+ end
370
+
371
+ describe "update user email" do
372
+ context "user doesn't exist" do
373
+ it "should not be ok" do
374
+ url = "#{Authy.api_uri}/protected/json/users/tony/update"
375
+ response_json = {
376
+ "message" => "User not found.",
377
+ "success" => false,
378
+ "errors" => {
379
+ "message" => "User not found."
380
+ },
381
+ "error_code" => "60026"
382
+ }.to_json
383
+ new_email = generate_email
384
+ expect(Authy::API.http_client).to receive(:request)
385
+ .once
386
+ .with(:post, url, {
387
+ :header => headers,
388
+ :body => Utils.escape_query(:email => new_email)
389
+ })
390
+ .and_return(double(:status => 404, :body => response_json))
391
+
392
+ response = Authy::API.update_user(id: "tony", email: new_email)
196
393
  expect(response.errors['message']).to eq "User not found."
197
394
  expect(response).to_not be_ok
198
395
  end
199
396
  end
200
397
 
201
398
  context "user exists" do
202
- before do
203
- @user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
204
- expect(@user).to be_ok
399
+ it "should be ok" do
400
+ response_json = {
401
+ "message" => "User was updated successfully",
402
+ "success" => true
403
+ }.to_json
404
+ url = "#{Authy.api_uri}/protected/json/users/#{user_id}/update"
405
+ new_email = generate_email
406
+ expect(Authy::API.http_client).to receive(:request)
407
+ .once
408
+ .with(:post, url, body: Utils.escape_query({
409
+ email: new_email
410
+ }), header: headers)
411
+ .and_return(double(ok?: true, body: response_json, status: 200))
412
+ response = Authy::API.update_user(id: user_id, email: new_email)
413
+ expect(response.message).to eq "User was updated successfully"
414
+ expect(response).to be_ok
205
415
  end
416
+ end
417
+ end
206
418
 
419
+ describe "delete users" do
420
+ context "user doesn't exist" do
421
+ it "should not be ok" do
422
+ url = "#{Authy.api_uri}/protected/json/users/delete/tony"
423
+ response_json = {
424
+ "message" => "User not found.",
425
+ "success" => false,
426
+ "errors" => {
427
+ "message" => "User not found."
428
+ },
429
+ "error_code" => "60026"
430
+ }.to_json
431
+ expect(Authy::API.http_client).to receive(:request)
432
+ .once
433
+ .with(:post, url, {
434
+ :header => headers,
435
+ :body => ""
436
+ })
437
+ .and_return(double(:status => 404, :body => response_json))
438
+ response = Authy::API.delete_user(id: "tony")
439
+ expect(response.errors["message"]).to eq "User not found."
440
+ expect(response).to_not be_ok
441
+ end
442
+ end
443
+
444
+ context "user exists" do
445
+ let(:url) { "#{Authy.api_uri}/protected/json/users/delete/31567" }
207
446
  it "should be ok" do
208
- response = Authy::API.delete_user(id: @user.id)
209
- expect(response.message).to eq "User was added to remove."
447
+ response_json = {
448
+ "message" => "User removed from application",
449
+ "success" => false
450
+ }.to_json
451
+ expect(Authy::API.http_client).to receive(:request)
452
+ .once
453
+ .with(:post, url, {
454
+ :header => headers,
455
+ :body => ""
456
+ })
457
+ .and_return(double(:status => 200, :body => response_json))
458
+ response = Authy::API.delete_user(id: 31567)
459
+ expect(response.message).to eq "User removed from application"
210
460
  expect(response).to be_ok
211
461
  end
212
462
  end
@@ -215,6 +465,23 @@ describe "Authy::API" do
215
465
  describe "user status" do
216
466
  context "user doesn't exist" do
217
467
  it "should not be ok" do
468
+ url = "#{Authy.api_uri}/protected/json/users/tony/status"
469
+ response_json = {
470
+ "message" => "User not found.",
471
+ "success" => false,
472
+ "errors" => {
473
+ "message" => "User not found."
474
+ },
475
+ "error_code" => "60026"
476
+ }.to_json
477
+ expect(Authy::API.http_client).to receive(:request)
478
+ .once
479
+ .with(:get, url, {
480
+ :header => headers,
481
+ :query => {},
482
+ :follow_redirect => nil
483
+ })
484
+ .and_return(double(:status => 404, :body => response_json))
218
485
  response = Authy::API.user_status(id: "tony")
219
486
  expect(response.errors["message"]).to eq "User not found."
220
487
  expect(response).to_not be_ok
@@ -222,13 +489,42 @@ describe "Authy::API" do
222
489
  end
223
490
 
224
491
  context "user exists" do
225
- before do
226
- @user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
227
- expect(@user).to be_ok
228
- end
229
-
230
492
  it "should be ok" do
231
- response = Authy::API.user_status(id: @user.id)
493
+ url = "#{Authy.api_uri}/protected/json/users/290907/status"
494
+ response_json = {
495
+ "status" => {
496
+ "authy_id" => 290907,
497
+ "confirmed" => true,
498
+ "registered" => false,
499
+ "country_code" => 1,
500
+ "phone_number" => "XXX-XXX-1118",
501
+ "email" => "alfvawmu@authy.com",
502
+ "devices" => [],
503
+ "has_hard_token" => false,
504
+ "account_disabled" => false,
505
+ "detailed_devices" => [{
506
+ "device_type" => "authy",
507
+ "os_type" => "unknown",
508
+ "registration_device_id" => nil,
509
+ "registration_method" => nil,
510
+ "device_id" => 290908,
511
+ "last_sync_date" => 0,
512
+ "creation_date" => 1433868212
513
+ }],
514
+ "deleted_devices" => []
515
+ },
516
+ "message" => "User status.",
517
+ "success" => true
518
+ }.to_json
519
+ expect(Authy::API.http_client).to receive(:request)
520
+ .once
521
+ .with(:get, url, {
522
+ :header => headers,
523
+ :query => {},
524
+ :follow_redirect => nil
525
+ })
526
+ .and_return(double(:status => 200, :body => response_json))
527
+ response = Authy::API.user_status(id: 290907)
232
528
  expect(response.status).to be_kind_of(Hash)
233
529
  expect(response).to be_ok
234
530
  end
@@ -236,13 +532,9 @@ describe "Authy::API" do
236
532
  end
237
533
 
238
534
  describe "blank params" do
239
- before do
240
- @user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
241
- expect(@user).to be_ok
242
- end
243
-
244
535
  [:request_sms, :request_phone_call, :delete_user].each do |method|
245
536
  it "should return a proper response with the errors for #{method}" do
537
+ expect(Authy::API.http_client).to receive(:request).never
246
538
  response = Authy::API.send(method, id: nil)
247
539
  expect(response).to_not be_ok
248
540
  expect(response.message).to eq "user_id is blank."
@@ -250,25 +542,26 @@ describe "Authy::API" do
250
542
  end
251
543
 
252
544
  it "should return a prope response with the errors for verify" do
545
+ expect(Authy::API.http_client).to receive(:request).never
253
546
  response = Authy::API.verify({})
254
547
  expect(response).to_not be_ok
255
548
  expect(response.message).to eq "Token format is invalid"
256
549
  end
257
550
  end
258
551
 
259
- describe '.token_is_safe?' do
260
- it 'checks minimum token size' do
261
- expect(Authy::API.send(:token_is_safe?, '1')).to be false
552
+ describe ".token_is_safe?" do
553
+ it "checks minimum token size" do
554
+ expect(Authy::API.send(:token_is_safe?, "1")).to be false
262
555
  end
263
556
 
264
- it 'checks valid characters' do
265
- expect(Authy::API.send(:token_is_safe?, '123456')).to be true
266
- expect(Authy::API.send(:token_is_safe?, '123456a')).to be false
557
+ it "checks valid characters" do
558
+ expect(Authy::API.send(:token_is_safe?, "123456")).to be true
559
+ expect(Authy::API.send(:token_is_safe?, "123456a")).to be false
267
560
  end
268
561
 
269
- it 'checks maximum token size' do
270
- expect(Authy::API.send(:token_is_safe?, '123456789098')).to be true
271
- expect(Authy::API.send(:token_is_safe?, '1234567890987')).to be false
562
+ it "checks maximum token size" do
563
+ expect(Authy::API.send(:token_is_safe?, "123456789098")).to be true
564
+ expect(Authy::API.send(:token_is_safe?, "1234567890987")).to be false
272
565
  end
273
566
  end
274
567
  end