authy 2.7.1 → 2.7.2
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 +4 -4
- data/.travis.yml +2 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +60 -57
- data/lib/authy/response.rb +4 -1
- data/lib/authy/version.rb +1 -1
- data/spec/authy/api_spec.rb +90 -92
- data/spec/authy/config_spec.rb +14 -14
- data/spec/authy/onetouch_spec.rb +5 -1
- data/spec/authy/phone_intelligence_spec.rb +35 -34
- data/spec/authy/phone_verification_spec.rb +41 -26
- data/spec/authy/response_spec.rb +36 -23
- data/spec/authy/url_helpers_spec.rb +5 -5
- data/spec/spec_helper.rb +0 -6
- metadata +3 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8113421bc21b13bc9ad8d67d40f0396448d3950f
|
|
4
|
+
data.tar.gz: e6d280e4e5e44a8a507531961d07c5e47199a122
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94643682f6f44bbbaab85beb4efc63b0a2c49c383571fc904b078d1e46f5c3e6e1cc96278366089a1a9bc3c7d049da1b81800f299ac6dd4f8b21e93cc3d53026
|
|
7
|
+
data.tar.gz: 4cd4391e4747294e2d66ea6aa93e55c27f2102f13d0ebbdef4c6240ecd4e20d922ec2bd7b139ce32eb8a99ff8864bfdde89fd98350aeeb4a8de7fb482c6ee3ef
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -2,101 +2,104 @@ GEM
|
|
|
2
2
|
remote: https://rubygems.org/
|
|
3
3
|
specs:
|
|
4
4
|
addressable (2.4.0)
|
|
5
|
-
ast (2.
|
|
5
|
+
ast (2.3.0)
|
|
6
6
|
axiom-types (0.1.1)
|
|
7
7
|
descendants_tracker (~> 0.0.4)
|
|
8
8
|
ice_nine (~> 0.11.0)
|
|
9
9
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
10
|
-
builder (3.2.
|
|
11
|
-
codeclimate-engine-rb (0.
|
|
10
|
+
builder (3.2.3)
|
|
11
|
+
codeclimate-engine-rb (0.4.1)
|
|
12
12
|
virtus (~> 1.0)
|
|
13
|
-
coderay (1.1.
|
|
13
|
+
coderay (1.1.2)
|
|
14
14
|
coercible (1.0.0)
|
|
15
15
|
descendants_tracker (~> 0.0.1)
|
|
16
16
|
descendants_tracker (0.0.4)
|
|
17
17
|
thread_safe (~> 0.3, >= 0.3.1)
|
|
18
|
-
diff-lcs (1.
|
|
18
|
+
diff-lcs (1.3)
|
|
19
19
|
docile (1.1.5)
|
|
20
20
|
equalizer (0.0.11)
|
|
21
21
|
faraday (0.9.2)
|
|
22
22
|
multipart-post (>= 1.2, < 3)
|
|
23
23
|
git (1.3.0)
|
|
24
|
-
github_api (0.
|
|
24
|
+
github_api (0.16.0)
|
|
25
25
|
addressable (~> 2.4.0)
|
|
26
26
|
descendants_tracker (~> 0.0.4)
|
|
27
27
|
faraday (~> 0.8, < 0.10)
|
|
28
28
|
hashie (>= 3.4)
|
|
29
|
-
|
|
30
|
-
oauth2
|
|
31
|
-
hashie (3.
|
|
32
|
-
highline (1.7.
|
|
33
|
-
httpclient (2.
|
|
29
|
+
mime-types (>= 1.16, < 3.0)
|
|
30
|
+
oauth2 (~> 1.0)
|
|
31
|
+
hashie (3.5.7)
|
|
32
|
+
highline (1.7.10)
|
|
33
|
+
httpclient (2.8.3)
|
|
34
34
|
ice_nine (0.11.2)
|
|
35
|
-
jeweler (2.
|
|
35
|
+
jeweler (2.3.7)
|
|
36
36
|
builder
|
|
37
|
-
bundler (>= 1
|
|
37
|
+
bundler (>= 1)
|
|
38
38
|
git (>= 1.2.5)
|
|
39
|
-
github_api
|
|
39
|
+
github_api (~> 0.16.0)
|
|
40
40
|
highline (>= 1.6.15)
|
|
41
41
|
nokogiri (>= 1.5.10)
|
|
42
|
+
psych (~> 2.2)
|
|
42
43
|
rake
|
|
43
44
|
rdoc
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
semver2
|
|
46
|
+
json (2.1.0)
|
|
47
|
+
jwt (1.5.6)
|
|
48
|
+
method_source (0.9.0)
|
|
49
|
+
mime-types (2.99.3)
|
|
50
|
+
mini_portile2 (2.3.0)
|
|
51
|
+
multi_json (1.12.2)
|
|
52
|
+
multi_xml (0.6.0)
|
|
50
53
|
multipart-post (2.0.0)
|
|
51
|
-
nokogiri (1.
|
|
52
|
-
mini_portile2 (~> 2.
|
|
53
|
-
oauth2 (1.
|
|
54
|
-
faraday (>= 0.8, < 0.
|
|
55
|
-
jwt (~> 1.0
|
|
54
|
+
nokogiri (1.8.1)
|
|
55
|
+
mini_portile2 (~> 2.3.0)
|
|
56
|
+
oauth2 (1.4.0)
|
|
57
|
+
faraday (>= 0.8, < 0.13)
|
|
58
|
+
jwt (~> 1.0)
|
|
56
59
|
multi_json (~> 1.3)
|
|
57
60
|
multi_xml (~> 0.5)
|
|
58
61
|
rack (>= 1.2, < 3)
|
|
59
|
-
parser (2.
|
|
60
|
-
ast (~> 2.
|
|
61
|
-
pry (0.
|
|
62
|
+
parser (2.4.0.2)
|
|
63
|
+
ast (~> 2.3)
|
|
64
|
+
pry (0.11.3)
|
|
62
65
|
coderay (~> 1.1.0)
|
|
63
|
-
method_source (~> 0.
|
|
64
|
-
|
|
65
|
-
rack (
|
|
66
|
-
rainbow (2.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
reek (4.
|
|
71
|
-
codeclimate-engine-rb (~> 0.
|
|
72
|
-
parser (
|
|
66
|
+
method_source (~> 0.9.0)
|
|
67
|
+
psych (2.2.4)
|
|
68
|
+
rack (2.0.3)
|
|
69
|
+
rainbow (2.2.2)
|
|
70
|
+
rake
|
|
71
|
+
rake (12.3.0)
|
|
72
|
+
rdoc (6.0.0)
|
|
73
|
+
reek (4.7.3)
|
|
74
|
+
codeclimate-engine-rb (~> 0.4.0)
|
|
75
|
+
parser (>= 2.4.0.0, < 2.5)
|
|
73
76
|
rainbow (~> 2.0)
|
|
74
|
-
rspec (3.
|
|
75
|
-
rspec-core (~> 3.
|
|
76
|
-
rspec-expectations (~> 3.
|
|
77
|
-
rspec-mocks (~> 3.
|
|
78
|
-
rspec-core (3.
|
|
79
|
-
rspec-support (~> 3.
|
|
80
|
-
rspec-expectations (3.
|
|
77
|
+
rspec (3.7.0)
|
|
78
|
+
rspec-core (~> 3.7.0)
|
|
79
|
+
rspec-expectations (~> 3.7.0)
|
|
80
|
+
rspec-mocks (~> 3.7.0)
|
|
81
|
+
rspec-core (3.7.0)
|
|
82
|
+
rspec-support (~> 3.7.0)
|
|
83
|
+
rspec-expectations (3.7.0)
|
|
81
84
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
82
|
-
rspec-support (~> 3.
|
|
83
|
-
rspec-mocks (3.
|
|
85
|
+
rspec-support (~> 3.7.0)
|
|
86
|
+
rspec-mocks (3.7.0)
|
|
84
87
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
85
|
-
rspec-support (~> 3.
|
|
86
|
-
rspec-support (3.
|
|
87
|
-
|
|
88
|
+
rspec-support (~> 3.7.0)
|
|
89
|
+
rspec-support (3.7.0)
|
|
90
|
+
semver2 (3.4.2)
|
|
91
|
+
simplecov (0.15.1)
|
|
88
92
|
docile (~> 1.1.0)
|
|
89
|
-
json (
|
|
93
|
+
json (>= 1.8, < 3)
|
|
90
94
|
simplecov-html (~> 0.10.0)
|
|
91
|
-
simplecov-html (0.10.
|
|
92
|
-
|
|
93
|
-
thread_safe (0.3.5)
|
|
95
|
+
simplecov-html (0.10.2)
|
|
96
|
+
thread_safe (0.3.6)
|
|
94
97
|
virtus (1.0.5)
|
|
95
98
|
axiom-types (~> 0.1)
|
|
96
99
|
coercible (~> 1.0)
|
|
97
100
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
|
98
101
|
equalizer (~> 0.0, >= 0.0.9)
|
|
99
|
-
yard (0.
|
|
102
|
+
yard (0.9.12)
|
|
100
103
|
|
|
101
104
|
PLATFORMS
|
|
102
105
|
ruby
|
|
@@ -109,7 +112,7 @@ DEPENDENCIES
|
|
|
109
112
|
reek
|
|
110
113
|
rspec
|
|
111
114
|
simplecov
|
|
112
|
-
yard
|
|
115
|
+
yard (~> 0.9.11)
|
|
113
116
|
|
|
114
117
|
BUNDLED WITH
|
|
115
|
-
1.
|
|
118
|
+
1.16.0
|
data/lib/authy/response.rb
CHANGED
|
@@ -39,6 +39,7 @@ module Authy
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
protected
|
|
42
|
+
|
|
42
43
|
def method_missing(name, *args, &block)
|
|
43
44
|
if self.include?(name.to_s)
|
|
44
45
|
self[name.to_s]
|
|
@@ -48,10 +49,12 @@ module Authy
|
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
def parse_body
|
|
51
|
-
body = JSON.parse(@raw_response.body)
|
|
52
|
+
body = JSON.parse(@raw_response.body)
|
|
52
53
|
body.each do |k,v|
|
|
53
54
|
self[k] = v
|
|
54
55
|
end
|
|
56
|
+
rescue
|
|
57
|
+
self['message'] = 'invalid json'
|
|
55
58
|
end
|
|
56
59
|
end
|
|
57
60
|
end
|
data/lib/authy/version.rb
CHANGED
data/spec/authy/api_spec.rb
CHANGED
|
@@ -1,71 +1,67 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe "Authy::API" do
|
|
4
|
-
|
|
5
4
|
describe "request headers" do
|
|
6
|
-
|
|
7
5
|
it "contains api key in header" do
|
|
8
|
-
|
|
6
|
+
expect_any_instance_of(HTTPClient).to receive(:request).twice.with( any_args, hash_including(header: { "X-Authy-API-Key" => Authy.api_key }) ) { double(ok?: true, body: "", status: 200) }
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
url = "protected/json/foo/2"
|
|
9
|
+
Authy::API.get_request(url, {})
|
|
10
|
+
Authy::API.post_request(url, {})
|
|
13
11
|
end
|
|
14
12
|
end
|
|
15
13
|
|
|
16
14
|
describe "Registering users" do
|
|
17
|
-
|
|
18
15
|
it "should find or create a user" do
|
|
19
16
|
user = Authy::API.register_user(
|
|
20
|
-
:
|
|
21
|
-
:
|
|
22
|
-
:
|
|
17
|
+
email: generate_email,
|
|
18
|
+
cellphone: generate_cellphone,
|
|
19
|
+
country_code: 1
|
|
23
20
|
)
|
|
24
|
-
user.should be_kind_of(Authy::Response)
|
|
25
21
|
|
|
26
|
-
user.
|
|
27
|
-
user.
|
|
28
|
-
user.
|
|
29
|
-
user.id.
|
|
22
|
+
expect(user).to be_kind_of(Authy::Response)
|
|
23
|
+
expect(user).to be_kind_of(Authy::User)
|
|
24
|
+
expect(user).to_not be_nil
|
|
25
|
+
expect(user.id).to_not be_nil
|
|
26
|
+
expect(user.id).to be_kind_of(Integer)
|
|
30
27
|
end
|
|
31
28
|
|
|
32
29
|
it "should return the error messages as a hash" do
|
|
33
30
|
user = Authy::API.register_user(
|
|
34
|
-
:
|
|
35
|
-
:
|
|
36
|
-
:
|
|
31
|
+
email: generate_email,
|
|
32
|
+
cellphone: "abc-1234",
|
|
33
|
+
country_code: 1
|
|
37
34
|
)
|
|
38
35
|
|
|
39
|
-
user.errors.
|
|
40
|
-
user.errors['cellphone'].
|
|
36
|
+
expect(user.errors).to be_kind_of(Hash)
|
|
37
|
+
expect(user.errors['cellphone']).to include 'is invalid'
|
|
41
38
|
end
|
|
42
39
|
|
|
43
40
|
it "should allow to override the API key" do
|
|
44
41
|
user = Authy::API.register_user(
|
|
45
|
-
:
|
|
46
|
-
:
|
|
47
|
-
:
|
|
48
|
-
:
|
|
42
|
+
email: generate_email,
|
|
43
|
+
cellphone: generate_cellphone,
|
|
44
|
+
country_code: 1,
|
|
45
|
+
api_key: "invalid_api_key"
|
|
49
46
|
)
|
|
50
47
|
|
|
51
|
-
user.
|
|
52
|
-
user.errors['message'].
|
|
48
|
+
expect(user).to_not be_ok
|
|
49
|
+
expect(user.errors['message']).to match(/invalid api key/i)
|
|
53
50
|
end
|
|
54
51
|
|
|
55
52
|
it "should allow overriding send_install_link_via_sms default" do
|
|
56
53
|
user = Authy::API.register_user(
|
|
57
|
-
:
|
|
58
|
-
:
|
|
59
|
-
:
|
|
60
|
-
:
|
|
54
|
+
email: generate_email,
|
|
55
|
+
cellphone: generate_cellphone,
|
|
56
|
+
country_code: 1,
|
|
57
|
+
send_install_link_via_sms: false # Default is true. See http://docs.authy.com/totp.html#totp-api
|
|
61
58
|
)
|
|
62
59
|
|
|
63
|
-
user.
|
|
64
|
-
|
|
65
|
-
user.
|
|
66
|
-
user.
|
|
67
|
-
user.id.
|
|
68
|
-
user.id.should be_kind_of(Integer)
|
|
60
|
+
expect(user).to be_kind_of(Authy::Response)
|
|
61
|
+
expect(user).to be_kind_of(Authy::User)
|
|
62
|
+
expect(user).to_not be_nil
|
|
63
|
+
expect(user.id).to_not be_nil
|
|
64
|
+
expect(user.id).to be_kind_of(Integer)
|
|
69
65
|
end
|
|
70
66
|
|
|
71
67
|
end
|
|
@@ -74,51 +70,53 @@ describe "Authy::API" do
|
|
|
74
70
|
before do
|
|
75
71
|
@email = generate_email
|
|
76
72
|
@cellphone = generate_cellphone
|
|
77
|
-
@user = Authy::API.register_user(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
@user = Authy::API.register_user(
|
|
74
|
+
email: @email,
|
|
75
|
+
cellphone: @cellphone,
|
|
76
|
+
country_code: 1
|
|
77
|
+
)
|
|
78
|
+
expect(@user).to be_ok
|
|
81
79
|
end
|
|
82
80
|
|
|
83
81
|
it "should fail to validate a given token if the user is not registered" do
|
|
84
|
-
response = Authy::API.verify(:
|
|
82
|
+
response = Authy::API.verify(token: 'invalid_token', id: @user.id)
|
|
85
83
|
|
|
86
|
-
response.
|
|
87
|
-
response.ok
|
|
88
|
-
response.errors['message'].
|
|
84
|
+
expect(response).to be_kind_of(Authy::Response)
|
|
85
|
+
expect(response.ok?).to be_falsey
|
|
86
|
+
expect(response.errors['message']).to include 'Token format is invalid'
|
|
89
87
|
end
|
|
90
88
|
|
|
91
89
|
it "should allow to override the API key" do
|
|
92
|
-
response = Authy::API.verify(:
|
|
90
|
+
response = Authy::API.verify(token: '123456', id: @user['id'], api_key: "invalid_api_key")
|
|
93
91
|
|
|
94
|
-
response.
|
|
95
|
-
response.errors['message'].
|
|
92
|
+
expect(response).to_not be_ok
|
|
93
|
+
expect(response.errors['message']).to match(/invalid api key/i)
|
|
96
94
|
end
|
|
97
95
|
|
|
98
96
|
it "should escape the params" do
|
|
99
|
-
expect
|
|
100
|
-
Authy::API.verify(:
|
|
101
|
-
|
|
97
|
+
expect do
|
|
98
|
+
Authy::API.verify(token: '[=#%@$&#(!@);.,', id: @user['id'])
|
|
99
|
+
end.to_not raise_error
|
|
102
100
|
end
|
|
103
101
|
|
|
104
102
|
it "should escape the params if have white spaces" do
|
|
105
|
-
expect
|
|
106
|
-
Authy::API.verify(:
|
|
107
|
-
|
|
103
|
+
expect do
|
|
104
|
+
Authy::API.verify(token: "token with space", id: @user['id'])
|
|
105
|
+
end.to_not raise_error
|
|
108
106
|
end
|
|
109
107
|
|
|
110
108
|
it "should fail if a param is missing" do
|
|
111
|
-
response = Authy::API.verify(:
|
|
112
|
-
response.
|
|
113
|
-
response.
|
|
114
|
-
response["message"]
|
|
109
|
+
response = Authy::API.verify(id: @user['id'])
|
|
110
|
+
expect(response).to be_kind_of(Authy::Response)
|
|
111
|
+
expect(response).to_not be_ok
|
|
112
|
+
expect(response["message"]).to include('Token format is invalid')
|
|
115
113
|
end
|
|
116
114
|
|
|
117
115
|
it 'fails when token format is invalid' do
|
|
118
|
-
response = Authy::API.verify(:
|
|
116
|
+
response = Authy::API.verify(token: '0000', id: @user.id)
|
|
119
117
|
|
|
120
118
|
expect(response.ok?).to be_falsey
|
|
121
|
-
response.
|
|
119
|
+
expect(response).to be_kind_of(Authy::Response)
|
|
122
120
|
expect(response.errors['message']).to eq 'Token format is invalid'
|
|
123
121
|
end
|
|
124
122
|
end
|
|
@@ -127,34 +125,34 @@ describe "Authy::API" do
|
|
|
127
125
|
title = kind.upcase
|
|
128
126
|
describe "Requesting #{title}" do
|
|
129
127
|
before do
|
|
130
|
-
@user = Authy::API.register_user(:
|
|
131
|
-
@user.
|
|
128
|
+
@user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
|
|
129
|
+
expect(@user).to be_ok
|
|
132
130
|
end
|
|
133
131
|
|
|
134
132
|
it "should request a #{title} token" do
|
|
135
133
|
uri_param = kind == "phone_call" ? "call" : kind
|
|
136
134
|
url = "#{Authy.api_uri}/protected/json/#{uri_param}/#{Authy::API.escape_for_url(@user.id)}"
|
|
137
|
-
HTTPClient.
|
|
138
|
-
response = Authy::API.send("request_#{kind}", :
|
|
139
|
-
response.
|
|
135
|
+
expect_any_instance_of(HTTPClient).to receive(:request).with(:get, url, {query:{}, header:{ "X-Authy-API-Key" => Authy.api_key }, follow_redirect:nil}) { double(ok?: true, body: "", status: 200) }
|
|
136
|
+
response = Authy::API.send("request_#{kind}", id: @user.id)
|
|
137
|
+
expect(response).to be_ok
|
|
140
138
|
end
|
|
141
139
|
|
|
142
140
|
it "should allow to override the API key" do
|
|
143
|
-
response = Authy::API.send("request_#{kind}", :
|
|
144
|
-
response.
|
|
145
|
-
response.errors['message'].
|
|
141
|
+
response = Authy::API.send("request_#{kind}", id: @user.id, api_key: "invalid_api_key")
|
|
142
|
+
expect(response).to_not be_ok
|
|
143
|
+
expect(response.errors['message']).to match(/invalid api key/i)
|
|
146
144
|
end
|
|
147
145
|
|
|
148
146
|
it "should request a #{title} token using custom actions" do
|
|
149
147
|
response = Authy::API.send("request_#{kind}", id: @user.id, action: "custom action?", action_message: "Action message $%^?@#")
|
|
150
|
-
response.
|
|
148
|
+
expect(response).to be_ok
|
|
151
149
|
end
|
|
152
150
|
|
|
153
151
|
context "user doesn't exist" do
|
|
154
152
|
it "should not be ok" do
|
|
155
|
-
response = Authy::API.send("request_#{kind}", :
|
|
156
|
-
response.errors['message'].
|
|
157
|
-
response.
|
|
153
|
+
response = Authy::API.send("request_#{kind}", id: "tony")
|
|
154
|
+
expect(response.errors['message']).to eq "User not found."
|
|
155
|
+
expect(response).to_not be_ok
|
|
158
156
|
end
|
|
159
157
|
end
|
|
160
158
|
end
|
|
@@ -163,22 +161,22 @@ describe "Authy::API" do
|
|
|
163
161
|
describe "delete users" do
|
|
164
162
|
context "user doesn't exist" do
|
|
165
163
|
it "should not be ok" do
|
|
166
|
-
response = Authy::API.delete_user(:
|
|
167
|
-
response.errors['message'].
|
|
168
|
-
response.
|
|
164
|
+
response = Authy::API.delete_user(id: "tony")
|
|
165
|
+
expect(response.errors['message']).to eq "User not found."
|
|
166
|
+
expect(response).to_not be_ok
|
|
169
167
|
end
|
|
170
168
|
end
|
|
171
169
|
|
|
172
170
|
context "user exists" do
|
|
173
171
|
before do
|
|
174
|
-
@user = Authy::API.register_user(:
|
|
175
|
-
@user.
|
|
172
|
+
@user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
|
|
173
|
+
expect(@user).to be_ok
|
|
176
174
|
end
|
|
177
175
|
|
|
178
176
|
it "should be ok" do
|
|
179
|
-
response = Authy::API.delete_user(:
|
|
180
|
-
response.message.
|
|
181
|
-
response.
|
|
177
|
+
response = Authy::API.delete_user(id: @user.id)
|
|
178
|
+
expect(response.message).to eq "User was added to remove."
|
|
179
|
+
expect(response).to be_ok
|
|
182
180
|
end
|
|
183
181
|
end
|
|
184
182
|
end
|
|
@@ -186,37 +184,37 @@ describe "Authy::API" do
|
|
|
186
184
|
describe "user status" do
|
|
187
185
|
context "user doesn't exist" do
|
|
188
186
|
it "should not be ok" do
|
|
189
|
-
response = Authy::API.user_status(:
|
|
190
|
-
response.errors["message"].
|
|
191
|
-
response.
|
|
187
|
+
response = Authy::API.user_status(id: "tony")
|
|
188
|
+
expect(response.errors["message"]).to eq "User not found."
|
|
189
|
+
expect(response).to_not be_ok
|
|
192
190
|
end
|
|
193
191
|
end
|
|
194
192
|
|
|
195
193
|
context "user exists" do
|
|
196
194
|
before do
|
|
197
|
-
@user = Authy::API.register_user(:
|
|
198
|
-
@user.
|
|
195
|
+
@user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
|
|
196
|
+
expect(@user).to be_ok
|
|
199
197
|
end
|
|
200
198
|
|
|
201
199
|
it "should be ok" do
|
|
202
|
-
response = Authy::API.user_status(:
|
|
203
|
-
response.status.
|
|
204
|
-
response.
|
|
200
|
+
response = Authy::API.user_status(id: @user.id)
|
|
201
|
+
expect(response.status).to be_kind_of(Hash)
|
|
202
|
+
expect(response).to be_ok
|
|
205
203
|
end
|
|
206
204
|
end
|
|
207
205
|
end
|
|
208
206
|
|
|
209
207
|
describe "blank params" do
|
|
210
208
|
before do
|
|
211
|
-
@user = Authy::API.register_user(:
|
|
212
|
-
@user.
|
|
209
|
+
@user = Authy::API.register_user(email: generate_email, cellphone: generate_cellphone, country_code: 1)
|
|
210
|
+
expect(@user).to be_ok
|
|
213
211
|
end
|
|
214
212
|
|
|
215
213
|
[:request_sms, :request_phone_call, :delete_user].each do |method|
|
|
216
214
|
it "should return a proper response with the errors for #{method}" do
|
|
217
|
-
response = Authy::API.send(method, :
|
|
218
|
-
response.
|
|
219
|
-
response.message.
|
|
215
|
+
response = Authy::API.send(method, id: nil)
|
|
216
|
+
expect(response).to_not be_ok
|
|
217
|
+
expect(response.message).to eq "user_id is blank."
|
|
220
218
|
end
|
|
221
219
|
end
|
|
222
220
|
|
data/spec/authy/config_spec.rb
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
4
|
-
describe
|
|
5
|
-
before
|
|
3
|
+
describe 'Authy' do
|
|
4
|
+
describe 'api_key' do
|
|
5
|
+
before do
|
|
6
6
|
@default_api_key = Authy.api_key
|
|
7
7
|
Authy.api_key = nil
|
|
8
|
-
ENV[
|
|
8
|
+
ENV['AUTHY_API_KEY'] = nil
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
after
|
|
11
|
+
after do
|
|
12
12
|
Authy.api_key = @default_api_key
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
it "should set and read instance variable" do
|
|
17
|
-
Authy.api_key =
|
|
18
|
-
Authy.api_key.
|
|
17
|
+
Authy.api_key = 'foo'
|
|
18
|
+
expect(Authy.api_key).to eq 'foo'
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it "should fallback to ENV variable" do
|
|
22
|
-
ENV[
|
|
23
|
-
Authy.api_key.
|
|
22
|
+
ENV['AUTHY_API_KEY'] = 'bar'
|
|
23
|
+
expect(Authy.api_key).to eq 'bar'
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
describe "api_url" do
|
|
28
|
-
before
|
|
28
|
+
before do
|
|
29
29
|
@default_api_url = Authy.api_url
|
|
30
30
|
Authy.api_url = nil
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
after
|
|
33
|
+
after do
|
|
34
34
|
Authy.api_url = @default_api_url
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
it "should set and read instance variable" do
|
|
38
|
-
Authy.api_url =
|
|
39
|
-
Authy.api_url.
|
|
38
|
+
Authy.api_url = 'https://example.com/'
|
|
39
|
+
expect(Authy.api_url).to eq 'https://example.com/'
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it "should fallback to default value" do
|
|
43
43
|
Authy.api_url = nil
|
|
44
|
-
Authy.api_url.
|
|
44
|
+
expect(Authy.api_url).to eq 'https://api.authy.com'
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
data/spec/authy/onetouch_spec.rb
CHANGED
|
@@ -9,10 +9,11 @@ describe Authy::OneTouch do
|
|
|
9
9
|
@user = Authy::API.register_user(:email => @email,
|
|
10
10
|
:cellphone => @cellphone,
|
|
11
11
|
:country_code => 1)
|
|
12
|
-
@user.
|
|
12
|
+
expect(@user).to be_ok
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
it 'creates a new approval_request for user' do
|
|
16
|
+
pending('The Authy account this test uses needs to have OneTouch enabled. Another option is to mock the API')
|
|
16
17
|
response = Authy::OneTouch.send_approval_request(
|
|
17
18
|
id: @user.id,
|
|
18
19
|
message: 'You are moving 10 BTC from your account',
|
|
@@ -48,6 +49,7 @@ describe Authy::OneTouch do
|
|
|
48
49
|
end
|
|
49
50
|
|
|
50
51
|
it 'does not require other fields as mandatory' do
|
|
52
|
+
pending('The Authy account this test uses needs to have OneTouch enabled. Another option is to mock the API')
|
|
51
53
|
response = Authy::OneTouch.send_approval_request(
|
|
52
54
|
id: @user.id,
|
|
53
55
|
message: 'Test message'
|
|
@@ -58,6 +60,7 @@ describe Authy::OneTouch do
|
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
it 'checks logos format' do
|
|
63
|
+
pending('The Authy account this test uses needs to have OneTouch enabled. Another option is to mock the API')
|
|
61
64
|
response = Authy::OneTouch.send_approval_request(
|
|
62
65
|
id: @user.id,
|
|
63
66
|
message: 'You are moving 10 BTC from your account',
|
|
@@ -79,6 +82,7 @@ describe Authy::OneTouch do
|
|
|
79
82
|
|
|
80
83
|
describe '.approval_request_status' do
|
|
81
84
|
it 'returns approval request status' do
|
|
85
|
+
pending('The Authy account this test uses needs to have OneTouch enabled. Another option is to mock the API')
|
|
82
86
|
response = Authy::OneTouch.approval_request_status(
|
|
83
87
|
uuid: '550e8400-e29b-41d4-a716-446655440000'
|
|
84
88
|
)
|
|
@@ -4,22 +4,23 @@ describe "Authy::PhoneIntelligence" do
|
|
|
4
4
|
describe "Sending the verification code" do
|
|
5
5
|
|
|
6
6
|
it "should send the code via SMS" do
|
|
7
|
+
pending("API is not returning expected response in this case. The test phone number is invalid.")
|
|
7
8
|
response = Authy::PhoneIntelligence.verification_start(
|
|
8
|
-
:
|
|
9
|
-
:
|
|
10
|
-
:
|
|
9
|
+
via: "sms",
|
|
10
|
+
country_code: "1",
|
|
11
|
+
phone_number: "111-111-1111"
|
|
11
12
|
)
|
|
12
13
|
|
|
13
|
-
response.
|
|
14
|
-
response.
|
|
15
|
-
response.message.
|
|
14
|
+
expect(response).to be_kind_of(Authy::Response)
|
|
15
|
+
expect(response).to be_ok
|
|
16
|
+
expect(response.message).to eq "Text message sent to +1 111-111-1111."
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
# it "should send the code via CALL" do
|
|
19
20
|
# response = Authy::PhoneIntelligence.verification_start(
|
|
20
|
-
# :
|
|
21
|
-
# :
|
|
22
|
-
# :
|
|
21
|
+
# via: "call",
|
|
22
|
+
# country_code: "1",
|
|
23
|
+
# phone_number: "111-111-1111"
|
|
23
24
|
# )
|
|
24
25
|
|
|
25
26
|
# response.should be_kind_of(Authy::Response)
|
|
@@ -31,63 +32,63 @@ describe "Authy::PhoneIntelligence" do
|
|
|
31
32
|
describe "validate the fields required" do
|
|
32
33
|
it "should return an error. Country code is required" do
|
|
33
34
|
response = Authy::PhoneIntelligence.verification_start(
|
|
34
|
-
:
|
|
35
|
-
:
|
|
35
|
+
via: "sms",
|
|
36
|
+
phone_number: "111-111-1111"
|
|
36
37
|
)
|
|
37
38
|
|
|
38
|
-
response.
|
|
39
|
-
response.errors['message']
|
|
39
|
+
expect(response).to_not be_ok
|
|
40
|
+
expect(response.errors['message']).to match(/country_code - Parameter is required/)
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
it "should return an error. Cellphone is invalid" do
|
|
43
44
|
response = Authy::PhoneIntelligence.verification_start(
|
|
44
|
-
:
|
|
45
|
-
:
|
|
46
|
-
:
|
|
45
|
+
via: "sms",
|
|
46
|
+
country_code: "1",
|
|
47
|
+
phone_number: "123"
|
|
47
48
|
)
|
|
48
49
|
|
|
49
|
-
response.
|
|
50
|
-
response.errors['message']
|
|
50
|
+
expect(response).to_not be_ok
|
|
51
|
+
expect(response.errors['message']).to match(/Phone number is invalid/)
|
|
51
52
|
end
|
|
52
53
|
end
|
|
53
54
|
|
|
54
55
|
describe "Check the verification code" do
|
|
55
56
|
it "should return success true if code is correct" do
|
|
56
|
-
pending("API is not returning expected response in this case.")
|
|
57
|
+
pending("API is not returning expected response in this case. The test phone number is invalid.")
|
|
57
58
|
|
|
58
59
|
response = Authy::PhoneIntelligence.verification_check(
|
|
59
|
-
:
|
|
60
|
-
:
|
|
61
|
-
:
|
|
60
|
+
country_code: "1",
|
|
61
|
+
phone_number: "111-111-1111",
|
|
62
|
+
verification_code: "0000"
|
|
62
63
|
)
|
|
63
64
|
|
|
64
|
-
response.
|
|
65
|
-
response.message.
|
|
65
|
+
expect(response).to be_ok
|
|
66
|
+
expect(response.message).to eq "Verification code is correct."
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
it "should return an error if code is incorrect" do
|
|
69
|
-
pending("API is not returning expected response in this case.")
|
|
70
|
+
pending("API is not returning expected response in this case. The test phone number is invalid.")
|
|
70
71
|
|
|
71
72
|
response = Authy::PhoneIntelligence.verification_check(
|
|
72
|
-
:
|
|
73
|
-
:
|
|
74
|
-
:
|
|
73
|
+
country_code: "1",
|
|
74
|
+
phone_number: "111-111-1111",
|
|
75
|
+
verification_code: "1234"
|
|
75
76
|
)
|
|
76
77
|
|
|
77
|
-
response.
|
|
78
|
-
response.message.
|
|
78
|
+
expect(response).to_not be_ok
|
|
79
|
+
expect(response.message).to eq 'Verification code is incorrect.'
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
82
|
|
|
82
83
|
describe "Requesting phone number information" do
|
|
83
84
|
it "should return the phone information" do
|
|
84
85
|
response = Authy::PhoneIntelligence.info(
|
|
85
|
-
:
|
|
86
|
-
:
|
|
86
|
+
country_code: '1',
|
|
87
|
+
phone_number: '7754615609'
|
|
87
88
|
)
|
|
88
89
|
|
|
89
|
-
response.
|
|
90
|
-
response.message.
|
|
90
|
+
expect(response).to be_ok
|
|
91
|
+
expect(response.message).to match(/Phone number information as of/)
|
|
91
92
|
end
|
|
92
93
|
end
|
|
93
94
|
end
|
|
@@ -4,22 +4,23 @@ describe "Authy::PhoneVerification" do
|
|
|
4
4
|
describe "Sending the verification code" do
|
|
5
5
|
|
|
6
6
|
it "should send the code via SMS" do
|
|
7
|
+
pending("API is not returning expected response in this case. The test phone number is invalid.")
|
|
7
8
|
response = Authy::PhoneVerification.start(
|
|
8
|
-
:
|
|
9
|
-
:
|
|
10
|
-
:
|
|
9
|
+
via: "sms",
|
|
10
|
+
country_code: "1",
|
|
11
|
+
phone_number: "111-111-1111"
|
|
11
12
|
)
|
|
12
13
|
|
|
13
|
-
response.
|
|
14
|
-
response.
|
|
15
|
-
response.message.
|
|
14
|
+
expect(response).to be_kind_of(Authy::Response)
|
|
15
|
+
expect(response).to be_ok
|
|
16
|
+
expect(response.message).to eq "Text message sent to +1 111-111-1111."
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
# it "should send the code via CALL" do
|
|
19
20
|
# response = Authy::PhoneVerification.start(
|
|
20
|
-
# :
|
|
21
|
-
# :
|
|
22
|
-
# :
|
|
21
|
+
# via: "call",
|
|
22
|
+
# country_code: "1",
|
|
23
|
+
# phone_number: "111-111-1111"
|
|
23
24
|
# )
|
|
24
25
|
|
|
25
26
|
# response.should be_kind_of(Authy::Response)
|
|
@@ -31,34 +32,35 @@ describe "Authy::PhoneVerification" do
|
|
|
31
32
|
describe "validate the fields required" do
|
|
32
33
|
it "should return an error. Country code is required" do
|
|
33
34
|
response = Authy::PhoneVerification.start(
|
|
34
|
-
:
|
|
35
|
-
:
|
|
35
|
+
via: "sms",
|
|
36
|
+
phone_number: "111-111-1111"
|
|
36
37
|
)
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
response.
|
|
39
|
+
|
|
40
|
+
expect(response).to_not be_ok
|
|
41
|
+
expect(response.errors['message']).to match(/country_code - Parameter is required/)
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
it "should return an error. Cellphone is invalid" do
|
|
43
45
|
response = Authy::PhoneVerification.start(
|
|
44
|
-
:
|
|
45
|
-
:
|
|
46
|
-
:
|
|
46
|
+
via: "sms",
|
|
47
|
+
country_code: "1",
|
|
48
|
+
phone_number: "123"
|
|
47
49
|
)
|
|
48
50
|
|
|
49
|
-
response.
|
|
50
|
-
response.errors['message']
|
|
51
|
+
expect(response).to_not be_ok
|
|
52
|
+
expect(response.errors['message']).to eq('Phone number is invalid')
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
|
|
54
56
|
describe "Check the verification code" do
|
|
55
57
|
it "should return success true if code is correct" do
|
|
56
|
-
pending("API is not returning expected response in this case.")
|
|
58
|
+
pending("API is not returning expected response in this case. The test phone number is invalid.")
|
|
57
59
|
|
|
58
60
|
response = Authy::PhoneVerification.check(
|
|
59
|
-
:
|
|
60
|
-
:
|
|
61
|
-
:
|
|
61
|
+
country_code: "1",
|
|
62
|
+
phone_number: "111-111-1111",
|
|
63
|
+
verification_code: "0000"
|
|
62
64
|
)
|
|
63
65
|
|
|
64
66
|
expect(response).to be_ok
|
|
@@ -66,16 +68,29 @@ describe "Authy::PhoneVerification" do
|
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
it "should return an error if code is incorrect" do
|
|
69
|
-
pending("API is not returning expected response in this case.")
|
|
71
|
+
pending("API is not returning expected response in this case. The test phone number is invalid")
|
|
70
72
|
|
|
71
73
|
response = Authy::PhoneVerification.check(
|
|
72
|
-
:
|
|
73
|
-
:
|
|
74
|
-
:
|
|
74
|
+
country_code: "1",
|
|
75
|
+
phone_number: "111-111-1111",
|
|
76
|
+
verification_code: "1234"
|
|
75
77
|
)
|
|
76
78
|
|
|
77
79
|
expect(response).not_to be_ok
|
|
78
80
|
expect(response.message).to eq('Verification code is incorrect.')
|
|
79
81
|
end
|
|
80
82
|
end
|
|
83
|
+
|
|
84
|
+
describe 'Check the phone number' do
|
|
85
|
+
it "should return an error if phone number is invalid" do
|
|
86
|
+
response = Authy::PhoneVerification.check(
|
|
87
|
+
country_code: "1",
|
|
88
|
+
phone_number: "111-111-1111",
|
|
89
|
+
verification_code: "1234"
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
expect(response).not_to be_ok
|
|
93
|
+
expect(response.message).to eq('Phone number is invalid')
|
|
94
|
+
end
|
|
95
|
+
end
|
|
81
96
|
end
|
data/spec/authy/response_spec.rb
CHANGED
|
@@ -1,33 +1,46 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe "Authy::Response" do
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
let(:response) { Authy::Response.new(fake_response) }
|
|
5
|
+
|
|
6
|
+
context 'response is valid' do
|
|
7
|
+
let(:fake_response) do
|
|
8
|
+
OpenStruct.new.tap do |struct|
|
|
9
|
+
struct.body = { 'v1' => 'r1','v2' => 42 }.to_json
|
|
10
|
+
struct.status = 200
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should parse to json the body" do
|
|
15
|
+
expect(response['v2']).to eq 42
|
|
16
|
+
expect(response.error_msg).to eq "No error"
|
|
17
|
+
expect(response.ok?).to be_truthy
|
|
18
|
+
end
|
|
14
19
|
end
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
context 'response returns a 401 status code' do
|
|
22
|
+
let(:fake_response) do
|
|
23
|
+
OpenStruct.new.tap do |struct|
|
|
24
|
+
struct.status = 401
|
|
25
|
+
end
|
|
26
|
+
end
|
|
18
27
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
it 'response is not ok' do
|
|
29
|
+
expect(response.ok?).to be_falsey
|
|
30
|
+
end
|
|
22
31
|
end
|
|
23
32
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
context 'response returns invalid json' do
|
|
34
|
+
let(:fake_response) do
|
|
35
|
+
OpenStruct.new.tap do |struct|
|
|
36
|
+
struct.body = 'invalid json'
|
|
37
|
+
struct.status = 401
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should return the error message" do
|
|
42
|
+
expect(response.error_msg).to eq "invalid json"
|
|
43
|
+
expect(response.message).to eq "invalid json"
|
|
44
|
+
end
|
|
32
45
|
end
|
|
33
46
|
end
|
|
@@ -7,30 +7,30 @@ describe "Authy::URL" do
|
|
|
7
7
|
|
|
8
8
|
describe "escape_for_url" do
|
|
9
9
|
it "should user URI escape" do
|
|
10
|
-
URI.
|
|
10
|
+
expect(URI).to receive :escape
|
|
11
11
|
Dummy.escape_for_url("that")
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it "should use Regexp" do
|
|
15
|
-
Regexp.
|
|
15
|
+
expect(Regexp).to receive(:new).with("[^#{URI::PATTERN::UNRESERVED}]").and_return(/a/)
|
|
16
16
|
Dummy.escape_for_url("that")
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
describe "to_param" do
|
|
21
21
|
it "should user HTTP::Message.escape" do
|
|
22
|
-
HTTP::Message.
|
|
22
|
+
expect(HTTP::Message).to receive(:escape).exactly(2).times.and_return "basic string"
|
|
23
23
|
Dummy.to_param('key', 'value')
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
it "should paramify the left to right" do
|
|
27
|
-
Dummy.to_param('key', 'value').
|
|
27
|
+
expect(Dummy.to_param('key', 'value')).to eq 'key=value'
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
describe "params_from_array" do
|
|
32
32
|
it "should return an array of params" do
|
|
33
|
-
Dummy.params_from_array("da key", ["one", "two"]).
|
|
33
|
+
expect(Dummy.params_from_array("da key", ["one", "two"])).to eq([HTTP::Message.escape("da key[]") + "=one", HTTP::Message.escape("da key[]") + "=two"])
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -15,12 +15,6 @@ RSpec.configure do |config|
|
|
|
15
15
|
Authy.api_key = 'bf12974d70818a08199d17d5e2bae630'
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
config.before(:each) do
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
config.after(:each) do
|
|
22
|
-
end
|
|
23
|
-
|
|
24
18
|
def generate_email
|
|
25
19
|
domain = "@authy.com"
|
|
26
20
|
user = (0...8).map{97.+(rand(25)).chr}.join
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: authy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.7.
|
|
4
|
+
version: 2.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Authy Inc
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-12-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: httpclient
|
|
@@ -181,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
181
181
|
version: '0'
|
|
182
182
|
requirements: []
|
|
183
183
|
rubyforge_project: authy
|
|
184
|
-
rubygems_version: 2.
|
|
184
|
+
rubygems_version: 2.5.2.1
|
|
185
185
|
signing_key:
|
|
186
186
|
specification_version: 4
|
|
187
187
|
summary: Ruby library to access Authy services
|
|
@@ -194,4 +194,3 @@ test_files:
|
|
|
194
194
|
- spec/authy/response_spec.rb
|
|
195
195
|
- spec/authy/url_helpers_spec.rb
|
|
196
196
|
- spec/spec_helper.rb
|
|
197
|
-
has_rdoc:
|