rodauth 1.18.0 → 1.19.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 +4 -4
- data/CHANGELOG +24 -0
- data/README.rdoc +20 -11
- data/doc/base.rdoc +2 -2
- data/doc/email_auth.rdoc +53 -0
- data/doc/email_base.rdoc +4 -0
- data/doc/internals.rdoc +3 -3
- data/doc/lockout.rdoc +28 -48
- data/doc/login.rdoc +4 -4
- data/doc/otp.rdoc +1 -3
- data/doc/release_notes/1.19.0.txt +116 -0
- data/doc/reset_password.rdoc +29 -49
- data/doc/verify_account.rdoc +30 -50
- data/doc/verify_login_change.rdoc +4 -0
- data/lib/rodauth/features/base.rb +0 -1
- data/lib/rodauth/features/change_login.rb +4 -0
- data/lib/rodauth/features/disallow_common_passwords.rb +1 -1
- data/lib/rodauth/features/email_auth.rb +253 -0
- data/lib/rodauth/features/email_base.rb +2 -0
- data/lib/rodauth/features/lockout.rb +35 -6
- data/lib/rodauth/features/login.rb +46 -9
- data/lib/rodauth/features/otp.rb +8 -4
- data/lib/rodauth/features/recovery_codes.rb +0 -2
- data/lib/rodauth/features/remember.rb +1 -1
- data/lib/rodauth/features/reset_password.rb +32 -4
- data/lib/rodauth/features/sms_codes.rb +2 -8
- data/lib/rodauth/features/two_factor_base.rb +22 -15
- data/lib/rodauth/features/verify_account.rb +27 -1
- data/lib/rodauth/features/verify_login_change.rb +30 -7
- data/lib/rodauth/migrations.rb +2 -8
- data/lib/rodauth/version.rb +1 -1
- data/spec/email_auth_spec.rb +285 -0
- data/spec/lockout_spec.rb +24 -2
- data/spec/login_spec.rb +47 -1
- data/spec/migrate/001_tables.rb +13 -0
- data/spec/migrate_travis/001_tables.rb +10 -0
- data/spec/reset_password_spec.rb +20 -2
- data/spec/two_factor_spec.rb +46 -0
- data/spec/verify_account_grace_period_spec.rb +1 -1
- data/spec/verify_account_spec.rb +33 -3
- data/spec/verify_login_change_spec.rb +54 -1
- data/templates/email-auth-email.str +5 -0
- data/templates/email-auth-request-form.str +7 -0
- data/templates/email-auth.str +5 -0
- data/templates/login-display.str +4 -0
- data/templates/login.str +2 -2
- data/templates/otp-setup.str +13 -11
- metadata +12 -2
@@ -6,6 +6,7 @@ module Rodauth
|
|
6
6
|
|
7
7
|
error_flash "Unable to verify account"
|
8
8
|
error_flash "Unable to resend verify account email", 'verify_account_resend'
|
9
|
+
error_flash "An email has recently been sent to you with a link to verify your account", 'verify_account_email_recently_sent'
|
9
10
|
notice_flash "Your account has been verified"
|
10
11
|
notice_flash "An email has been sent to you with a link to verify your account", 'verify_account_email_sent'
|
11
12
|
loaded_templates %w'verify-account verify-account-resend verify-account-email'
|
@@ -20,7 +21,8 @@ module Rodauth
|
|
20
21
|
button 'Verify Account'
|
21
22
|
button 'Send Verification Email Again', 'verify_account_resend'
|
22
23
|
redirect
|
23
|
-
redirect(:verify_account_email_sent){
|
24
|
+
redirect(:verify_account_email_sent){default_post_email_redirect}
|
25
|
+
redirect(:verify_account_email_recently_sent){default_post_email_redirect}
|
24
26
|
|
25
27
|
auth_value_method :no_matching_verify_account_key_message, "invalid verify account key"
|
26
28
|
auth_value_method :attempt_to_create_unverified_account_notice_message, "The account you tried to create is currently awaiting verification"
|
@@ -30,6 +32,8 @@ module Rodauth
|
|
30
32
|
auth_value_method :verify_account_autologin?, true
|
31
33
|
auth_value_method :verify_account_table, :account_verification_keys
|
32
34
|
auth_value_method :verify_account_id_column, :id
|
35
|
+
auth_value_method :verify_account_email_last_sent_column, nil
|
36
|
+
auth_value_method :verify_account_skip_resend_email_within, 300
|
33
37
|
auth_value_method :verify_account_key_column, :key
|
34
38
|
session_key :verify_account_session_key, :verify_account_key
|
35
39
|
auth_value_method :verify_account_set_password?, false
|
@@ -63,6 +67,11 @@ module Rodauth
|
|
63
67
|
|
64
68
|
r.post do
|
65
69
|
if account_from_login(param(login_param)) && allow_resending_verify_account_email?
|
70
|
+
if verify_account_email_recently_sent?
|
71
|
+
set_redirect_error_flash verify_account_email_recently_sent_error_flash
|
72
|
+
redirect verify_account_email_recently_sent_redirect
|
73
|
+
end
|
74
|
+
|
66
75
|
before_verify_account_email_resend
|
67
76
|
if verify_account_email_resend
|
68
77
|
after_verify_account_email_resend
|
@@ -158,6 +167,7 @@ module Rodauth
|
|
158
167
|
|
159
168
|
def verify_account_email_resend
|
160
169
|
if @verify_account_key_value = get_verify_account_key(account_id)
|
170
|
+
set_verify_account_email_last_sent
|
161
171
|
send_verify_account_email
|
162
172
|
true
|
163
173
|
end
|
@@ -218,8 +228,24 @@ module Rodauth
|
|
218
228
|
super
|
219
229
|
end
|
220
230
|
|
231
|
+
def set_verify_account_email_last_sent
|
232
|
+
verify_account_ds.update(verify_account_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if verify_account_email_last_sent_column
|
233
|
+
end
|
234
|
+
|
235
|
+
def get_verify_account_email_last_sent
|
236
|
+
if column = verify_account_email_last_sent_column
|
237
|
+
if ts = verify_account_ds.get(column)
|
238
|
+
convert_timestamp(ts)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
221
243
|
private
|
222
244
|
|
245
|
+
def verify_account_email_recently_sent?
|
246
|
+
(email_last_sent = get_verify_account_email_last_sent) && (Time.now - email_last_sent < verify_account_skip_resend_email_within)
|
247
|
+
end
|
248
|
+
|
223
249
|
attr_reader :verify_account_key_value
|
224
250
|
|
225
251
|
def before_login_attempt
|
@@ -5,14 +5,18 @@ module Rodauth
|
|
5
5
|
depends :change_login, :email_base
|
6
6
|
|
7
7
|
error_flash "Unable to verify login change"
|
8
|
+
error_flash "Unable to change login as there is already an account with the new login", :verify_login_change_duplicate_account
|
8
9
|
notice_flash "Your login change has been verified"
|
9
10
|
loaded_templates %w'verify-login-change verify-login-change-email'
|
10
11
|
view 'verify-login-change', 'Verify Login Change'
|
11
12
|
additional_form_tags
|
12
13
|
after
|
14
|
+
after 'verify_login_change_email'
|
13
15
|
before
|
16
|
+
before 'verify_login_change_email'
|
14
17
|
button 'Verify Login Change'
|
15
18
|
redirect
|
19
|
+
redirect(:verify_login_change_duplicate_account){require_login_redirect}
|
16
20
|
|
17
21
|
auth_value_method :no_matching_verify_login_change_key_message, "invalid verify login change key"
|
18
22
|
auth_value_method :verify_login_change_autologin?, false
|
@@ -76,7 +80,11 @@ module Rodauth
|
|
76
80
|
|
77
81
|
transaction do
|
78
82
|
before_verify_login_change
|
79
|
-
verify_login_change
|
83
|
+
unless verify_login_change
|
84
|
+
set_redirect_error_status(invalid_key_error_status)
|
85
|
+
set_redirect_error_flash verify_login_change_duplicate_account_error_flash
|
86
|
+
redirect verify_login_change_duplicate_account_redirect
|
87
|
+
end
|
80
88
|
remove_verify_login_change_key
|
81
89
|
after_verify_login_change
|
82
90
|
end
|
@@ -96,7 +104,11 @@ module Rodauth
|
|
96
104
|
end
|
97
105
|
|
98
106
|
def verify_login_change
|
99
|
-
|
107
|
+
unless res = _update_login(verify_login_change_new_login)
|
108
|
+
remove_verify_login_change_key
|
109
|
+
end
|
110
|
+
|
111
|
+
res
|
100
112
|
end
|
101
113
|
|
102
114
|
def account_from_verify_login_change_key(key)
|
@@ -134,10 +146,21 @@ module Rodauth
|
|
134
146
|
end
|
135
147
|
|
136
148
|
def update_login(login)
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
149
|
+
if _account_from_login(login)
|
150
|
+
@login_requirement_message = 'already an account with this login'
|
151
|
+
return false
|
152
|
+
end
|
153
|
+
|
154
|
+
transaction do
|
155
|
+
before_verify_login_change_email
|
156
|
+
generate_verify_login_change_key_value
|
157
|
+
@verify_login_change_new_login = login
|
158
|
+
create_verify_login_change_key(login)
|
159
|
+
send_verify_login_change_email(login)
|
160
|
+
after_verify_login_change_email
|
161
|
+
end
|
162
|
+
|
163
|
+
true
|
141
164
|
end
|
142
165
|
|
143
166
|
def generate_verify_login_change_key_value
|
@@ -150,7 +173,7 @@ module Rodauth
|
|
150
173
|
ds.where((Sequel::CURRENT_TIMESTAMP > verify_login_change_deadline_column) | ~Sequel.expr(verify_login_change_login_column=>login)).delete
|
151
174
|
if e = raised_uniqueness_violation{ds.insert(verify_login_change_key_insert_hash(login))}
|
152
175
|
old_login, key = get_verify_login_change_login_and_key(account_id)
|
153
|
-
# If inserting into the verify
|
176
|
+
# If inserting into the verify login change table causes a violation, we can pull the
|
154
177
|
# key from the verify login change table if the logins match, or reraise.
|
155
178
|
@verify_login_change_key_value = if old_login.downcase == login.downcase
|
156
179
|
key
|
data/lib/rodauth/migrations.rb
CHANGED
@@ -43,15 +43,9 @@ CREATE FUNCTION #{get_salt_name}(acct_id int8) RETURNS varchar(255)
|
|
43
43
|
SQL SECURITY DEFINER
|
44
44
|
READS SQL DATA
|
45
45
|
BEGIN
|
46
|
-
|
47
|
-
DECLARE csr CURSOR FOR
|
48
|
-
SELECT substr(password_hash, 1, 30)
|
46
|
+
RETURN (SELECT substr(password_hash, 1, 30)
|
49
47
|
FROM #{table_name}
|
50
|
-
WHERE acct_id = id;
|
51
|
-
OPEN csr;
|
52
|
-
FETCH csr INTO salt;
|
53
|
-
CLOSE csr;
|
54
|
-
RETURN salt;
|
48
|
+
WHERE acct_id = id);
|
55
49
|
END;
|
56
50
|
END
|
57
51
|
|
data/lib/rodauth/version.rb
CHANGED
@@ -0,0 +1,285 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe 'Rodauth email auth feature' do
|
4
|
+
it "should support logging in use link sent via email, without a password for the account" do
|
5
|
+
rodauth do
|
6
|
+
enable :login, :email_auth, :logout
|
7
|
+
account_password_hash_column :ph
|
8
|
+
end
|
9
|
+
roda do |r|
|
10
|
+
r.rodauth
|
11
|
+
r.root{view :content=>""}
|
12
|
+
end
|
13
|
+
|
14
|
+
DB[:accounts].update(:ph=>nil).must_equal 1
|
15
|
+
|
16
|
+
visit '/login'
|
17
|
+
fill_in 'Login', :with=>'foo2@example.com'
|
18
|
+
click_button 'Login'
|
19
|
+
page.find('#error_flash').text.must_equal 'There was an error logging in'
|
20
|
+
page.html.must_include("no matching login")
|
21
|
+
|
22
|
+
fill_in 'Login', :with=>'foo@example.com'
|
23
|
+
click_button 'Login'
|
24
|
+
page.find('#notice_flash').text.must_equal "An email has been sent to you with a link to login to your account"
|
25
|
+
page.current_path.must_equal '/'
|
26
|
+
link = email_link(/(\/email-auth\?key=.+)$/)
|
27
|
+
|
28
|
+
visit link[0...-1]
|
29
|
+
page.find('#error_flash').text.must_equal "invalid email authentication key"
|
30
|
+
|
31
|
+
visit '/login'
|
32
|
+
fill_in 'Login', :with=>'foo@example.com'
|
33
|
+
click_button 'Login'
|
34
|
+
page.find('#error_flash').text.must_equal "An email has recently been sent to you with a link to login"
|
35
|
+
Mail::TestMailer.deliveries.must_equal []
|
36
|
+
|
37
|
+
DB[:account_email_auth_keys].update(:email_last_sent => Time.now - 250).must_equal 1
|
38
|
+
visit '/login'
|
39
|
+
fill_in 'Login', :with=>'foo@example.com'
|
40
|
+
click_button 'Login'
|
41
|
+
page.find('#error_flash').text.must_equal "An email has recently been sent to you with a link to login"
|
42
|
+
Mail::TestMailer.deliveries.must_equal []
|
43
|
+
|
44
|
+
DB[:account_email_auth_keys].update(:email_last_sent => Time.now - 350).must_equal 1
|
45
|
+
visit '/login'
|
46
|
+
fill_in 'Login', :with=>'foo@example.com'
|
47
|
+
click_button 'Login'
|
48
|
+
email_link(/(\/email-auth\?key=.+)$/).must_equal link
|
49
|
+
|
50
|
+
visit link
|
51
|
+
page.title.must_equal 'Login'
|
52
|
+
click_button 'Login'
|
53
|
+
page.find('#notice_flash').text.must_equal 'You have been logged in'
|
54
|
+
page.current_path.must_equal '/'
|
55
|
+
|
56
|
+
logout
|
57
|
+
|
58
|
+
visit link
|
59
|
+
visit '/login'
|
60
|
+
fill_in 'Login', :with=>'foo@example.com'
|
61
|
+
click_button 'Login'
|
62
|
+
|
63
|
+
link2 = email_link(/(\/email-auth\?key=.+)$/)
|
64
|
+
link2.wont_equal link
|
65
|
+
|
66
|
+
visit link2
|
67
|
+
DB[:account_email_auth_keys].update(:deadline => Time.now - 60).must_equal 1
|
68
|
+
click_button 'Login'
|
69
|
+
page.find('#error_flash').text.must_equal "There was an error logging you in"
|
70
|
+
page.current_path.must_equal '/'
|
71
|
+
DB[:account_email_auth_keys].count.must_equal 0
|
72
|
+
|
73
|
+
visit '/login'
|
74
|
+
fill_in 'Login', :with=>'foo@example.com'
|
75
|
+
click_button 'Login'
|
76
|
+
|
77
|
+
visit email_link(/(\/email-auth\?key=.+)$/)
|
78
|
+
DB[:account_email_auth_keys].update(:key=>'1').must_equal 1
|
79
|
+
click_button 'Login'
|
80
|
+
page.find('#error_flash').text.must_equal "There was an error logging you in"
|
81
|
+
page.current_path.must_equal '/'
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should support logging in use link sent via email, with a password for the account" do
|
85
|
+
rodauth do
|
86
|
+
enable :login, :email_auth, :logout
|
87
|
+
email_auth_email_last_sent_column nil
|
88
|
+
end
|
89
|
+
roda do |r|
|
90
|
+
r.rodauth
|
91
|
+
r.root{view :content=>""}
|
92
|
+
end
|
93
|
+
|
94
|
+
visit '/login'
|
95
|
+
fill_in 'Login', :with=>'foo2@example.com'
|
96
|
+
click_button 'Login'
|
97
|
+
page.find('#error_flash').text.must_equal 'There was an error logging in'
|
98
|
+
page.html.must_include("no matching login")
|
99
|
+
|
100
|
+
fill_in 'Login', :with=>'foo@example.com'
|
101
|
+
click_button 'Login'
|
102
|
+
click_button 'Send Login Link Via Email'
|
103
|
+
page.find('#notice_flash').text.must_equal "An email has been sent to you with a link to login to your account"
|
104
|
+
page.current_path.must_equal '/'
|
105
|
+
link = email_link(/(\/email-auth\?key=.+)$/)
|
106
|
+
|
107
|
+
visit link[0...-1]
|
108
|
+
page.find('#error_flash').text.must_equal "invalid email authentication key"
|
109
|
+
|
110
|
+
visit '/login'
|
111
|
+
fill_in 'Login', :with=>'foo@example.com'
|
112
|
+
click_button 'Login'
|
113
|
+
click_button 'Send Login Link Via Email'
|
114
|
+
email_link(/(\/email-auth\?key=.+)$/).must_equal link
|
115
|
+
|
116
|
+
visit link
|
117
|
+
page.title.must_equal 'Login'
|
118
|
+
click_button 'Login'
|
119
|
+
page.find('#notice_flash').text.must_equal 'You have been logged in'
|
120
|
+
page.current_path.must_equal '/'
|
121
|
+
|
122
|
+
logout
|
123
|
+
|
124
|
+
visit link
|
125
|
+
visit '/login'
|
126
|
+
fill_in 'Login', :with=>'foo@example.com'
|
127
|
+
click_button 'Login'
|
128
|
+
click_button 'Send Login Link Via Email'
|
129
|
+
|
130
|
+
link2 = email_link(/(\/email-auth\?key=.+)$/)
|
131
|
+
link2.wont_equal link
|
132
|
+
|
133
|
+
visit link2
|
134
|
+
DB[:account_email_auth_keys].update(:deadline => Time.now - 60).must_equal 1
|
135
|
+
click_button 'Login'
|
136
|
+
page.find('#error_flash').text.must_equal "There was an error logging you in"
|
137
|
+
page.current_path.must_equal '/'
|
138
|
+
DB[:account_email_auth_keys].count.must_equal 0
|
139
|
+
|
140
|
+
visit '/login'
|
141
|
+
fill_in 'Login', :with=>'foo@example.com'
|
142
|
+
click_button 'Login'
|
143
|
+
click_button 'Send Login Link Via Email'
|
144
|
+
|
145
|
+
visit email_link(/(\/email-auth\?key=.+)$/)
|
146
|
+
DB[:account_email_auth_keys].update(:key=>'1').must_equal 1
|
147
|
+
click_button 'Login'
|
148
|
+
page.find('#error_flash').text.must_equal "There was an error logging you in"
|
149
|
+
page.current_path.must_equal '/'
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should allow password login for accounts with password hashes" do
|
153
|
+
rodauth do
|
154
|
+
enable :login, :email_auth
|
155
|
+
end
|
156
|
+
roda do |r|
|
157
|
+
r.rodauth
|
158
|
+
next unless rodauth.logged_in?
|
159
|
+
r.root{view :content=>"Logged In"}
|
160
|
+
end
|
161
|
+
|
162
|
+
visit '/login'
|
163
|
+
page.title.must_equal 'Login'
|
164
|
+
fill_in 'Login', :with=>'foo@example.com'
|
165
|
+
click_button 'Login'
|
166
|
+
page.html.must_include 'Send Login Link Via Email'
|
167
|
+
fill_in 'Password', :with=>'0123456789'
|
168
|
+
click_button 'Login'
|
169
|
+
page.current_path.must_equal '/'
|
170
|
+
page.find('#notice_flash').text.must_equal 'You have been logged in'
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should work with creating accounts without setting passwords" do
|
174
|
+
rodauth do
|
175
|
+
enable :login, :create_account, :email_auth
|
176
|
+
require_login_confirmation? false
|
177
|
+
create_account_autologin? false
|
178
|
+
create_account_set_password? false
|
179
|
+
end
|
180
|
+
roda do |r|
|
181
|
+
r.rodauth
|
182
|
+
r.root{view :content=>""}
|
183
|
+
end
|
184
|
+
|
185
|
+
visit '/create-account'
|
186
|
+
fill_in 'Login', :with=>'foo@example2.com'
|
187
|
+
click_button 'Create Account'
|
188
|
+
page.find('#notice_flash').text.must_equal "Your account has been created"
|
189
|
+
|
190
|
+
visit '/login'
|
191
|
+
fill_in 'Login', :with=>'foo@example2.com'
|
192
|
+
click_button 'Login'
|
193
|
+
page.current_path.must_equal '/'
|
194
|
+
visit email_link(/(\/email-auth\?key=.+)$/, 'foo@example2.com')
|
195
|
+
page.title.must_equal 'Login'
|
196
|
+
click_button 'Login'
|
197
|
+
page.find('#notice_flash').text.must_equal 'You have been logged in'
|
198
|
+
page.current_path.must_equal '/'
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should clear email auth token when closing account" do
|
202
|
+
rodauth do
|
203
|
+
enable :login, :email_auth, :close_account
|
204
|
+
end
|
205
|
+
roda do |r|
|
206
|
+
r.rodauth
|
207
|
+
r.root{view :content=>rodauth.logged_in? ? "Logged In" : "Not Logged"}
|
208
|
+
end
|
209
|
+
|
210
|
+
visit '/login'
|
211
|
+
page.title.must_equal 'Login'
|
212
|
+
fill_in 'Login', :with=>'foo@example.com'
|
213
|
+
click_button 'Login'
|
214
|
+
click_button 'Send Login Link Via Email'
|
215
|
+
|
216
|
+
hash = DB[:account_email_auth_keys].first
|
217
|
+
|
218
|
+
visit email_link(/(\/email-auth\?key=.+)$/)
|
219
|
+
click_button 'Login'
|
220
|
+
|
221
|
+
DB[:account_email_auth_keys].count.must_equal 0
|
222
|
+
DB[:account_email_auth_keys].insert(hash)
|
223
|
+
|
224
|
+
visit '/close-account'
|
225
|
+
fill_in 'Password', :with=>'0123456789'
|
226
|
+
click_button 'Close Account'
|
227
|
+
DB[:account_email_auth_keys].count.must_equal 0
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should handle uniqueness errors raised when inserting email auth token" do
|
231
|
+
rodauth do
|
232
|
+
enable :login, :email_auth
|
233
|
+
end
|
234
|
+
roda do |r|
|
235
|
+
def rodauth.raised_uniqueness_violation(*) super; true; end
|
236
|
+
r.rodauth
|
237
|
+
r.root{view :content=>""}
|
238
|
+
end
|
239
|
+
|
240
|
+
visit '/login'
|
241
|
+
page.title.must_equal 'Login'
|
242
|
+
fill_in 'Login', :with=>'foo@example.com'
|
243
|
+
click_button 'Login'
|
244
|
+
click_button 'Send Login Link Via Email'
|
245
|
+
link = email_link(/(\/email-auth\?key=.+)$/)
|
246
|
+
|
247
|
+
DB[:account_email_auth_keys].update(:email_last_sent => Time.now - 350).must_equal 1
|
248
|
+
visit '/login'
|
249
|
+
page.title.must_equal 'Login'
|
250
|
+
fill_in 'Login', :with=>'foo@example.com'
|
251
|
+
click_button 'Login'
|
252
|
+
click_button 'Send Login Link Via Email'
|
253
|
+
email_link(/(\/email-auth\?key=.+)$/).must_equal link
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should support email auth for accounts via jwt" do
|
257
|
+
rodauth do
|
258
|
+
enable :login, :email_auth
|
259
|
+
email_auth_email_body{email_auth_email_link}
|
260
|
+
end
|
261
|
+
roda(:jwt) do |r|
|
262
|
+
r.rodauth
|
263
|
+
end
|
264
|
+
|
265
|
+
res = json_request('/email-auth-request')
|
266
|
+
res.must_equal [401, {"error"=>"There was an error requesting an email link to authenticate"}]
|
267
|
+
|
268
|
+
res = json_request('/email-auth-request', :login=>'foo@example2.com')
|
269
|
+
res.must_equal [401, {"error"=>"There was an error requesting an email link to authenticate"}]
|
270
|
+
|
271
|
+
res = json_request('/email-auth-request', :login=>'foo@example.com')
|
272
|
+
res.must_equal [200, {"success"=>"An email has been sent to you with a link to login to your account"}]
|
273
|
+
|
274
|
+
link = email_link(/key=.+$/)
|
275
|
+
res = json_request('/email-auth')
|
276
|
+
res.must_equal [401, {"error"=>"There was an error logging you in"}]
|
277
|
+
|
278
|
+
res = json_request('/email-auth', :key=>link[4...-1])
|
279
|
+
res.must_equal [401, {"error"=>"There was an error logging you in"}]
|
280
|
+
|
281
|
+
res = json_request('/email-auth', :key=>link[4..-1])
|
282
|
+
res.must_equal [200, {"success"=>"You have been logged in"}]
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|