card 1.16.12 → 1.16.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/card.gemspec +1 -1
- data/db/migrate_core_cards/20130823192433_add_style_cards.rb +39 -24
- data/db/migrate_core_cards/20140629222005_add_email_cards.rb +6 -11
- data/db/migrate_core_cards/20151120180631_add_token_expiration.rb +7 -0
- data/db/seed/new/card_actions.yml +396 -388
- data/db/seed/new/card_acts.yml +1 -595
- data/db/seed/new/card_changes.yml +8154 -23619
- data/db/seed/new/card_references.yml +1009 -988
- data/db/seed/new/cards.yml +1445 -1423
- data/db/seed/test/fixtures/card_actions.yml +1375 -1399
- data/db/seed/test/fixtures/card_acts.yml +445 -1063
- data/db/seed/test/fixtures/card_changes.yml +11440 -26881
- data/db/seed/test/fixtures/card_references.yml +1523 -1502
- data/db/seed/test/fixtures/cards.yml +2736 -2715
- data/db/seed/test/seed.rb +7 -10
- data/db/version_core_cards.txt +1 -1
- data/lib/card/auth.rb +65 -19
- data/lib/card/cache.rb +18 -18
- data/lib/card/env.rb +10 -10
- data/lib/card/format.rb +41 -30
- data/lib/card/location.rb +3 -5
- data/lib/card/subcards.rb +0 -3
- data/lib/card/success.rb +14 -11
- data/mod/01_core/set/all/subcards.rb +4 -2
- data/mod/01_core/set/all/trash.rb +4 -1
- data/mod/02_basic_types/set/type/pointer.rb +5 -2
- data/mod/05_email/set/all/notify.rb +85 -73
- data/mod/05_email/spec/set/all/notify_spec.rb +74 -55
- data/mod/05_standard/set/all/comment.rb +18 -12
- data/mod/05_standard/set/all/error.rb +5 -1
- data/mod/05_standard/set/right/account.rb +50 -73
- data/mod/05_standard/set/right/token.rb +49 -2
- data/mod/05_standard/set/self/signin.rb +14 -12
- data/mod/05_standard/set/type/signup.rb +17 -21
- data/mod/05_standard/spec/set/all/account_spec.rb +1 -1
- data/mod/05_standard/spec/set/right/account_spec.rb +76 -52
- data/mod/05_standard/spec/set/right/password_spec.rb +10 -11
- data/mod/05_standard/spec/set/right/token_spec.rb +19 -1
- data/mod/05_standard/spec/set/type/signup_spec.rb +3 -4
- data/spec/lib/card/auth_spec.rb +46 -5
- metadata +5 -4
@@ -1,16 +1,22 @@
|
|
1
|
-
event :add_comment, after: :approve, on: :save, when: proc {|c| c.comment } do
|
1
|
+
event :add_comment, after: :approve, on: :save, when: proc { |c| c.comment } do
|
2
|
+
cleaned_comment =
|
3
|
+
comment.split(/\n/).map do |line|
|
4
|
+
"<p>#{line.strip.empty? ? ' ' : line}</p>"
|
5
|
+
end * "\n"
|
6
|
+
|
7
|
+
signature =
|
8
|
+
if Auth.signed_in?
|
9
|
+
"[[#{Auth.current.name}]]"
|
10
|
+
else
|
11
|
+
Env.session[:comment_author] = comment_author if Env.session
|
12
|
+
"#{ comment_author } (Not signed in)"
|
13
|
+
end
|
14
|
+
|
2
15
|
self.content = %{
|
3
|
-
#{
|
4
|
-
#{
|
5
|
-
#{
|
6
|
-
<div class="w-comment-author">--#{
|
7
|
-
if Auth.signed_in?
|
8
|
-
"[[#{Auth.current.name}]]"
|
9
|
-
else
|
10
|
-
Env.session[:comment_author] = comment_author if Env.session
|
11
|
-
"#{ comment_author } (Not signed in)"
|
12
|
-
end
|
13
|
-
}.....#{Time.now}</div>
|
16
|
+
#{content}
|
17
|
+
#{'<hr>' unless content.blank?}
|
18
|
+
#{cleaned_comment}
|
19
|
+
<div class="w-comment-author">--#{signature}.....#{Time.now}</div>
|
14
20
|
}
|
15
21
|
end
|
16
22
|
|
@@ -12,36 +12,19 @@ def blocked?; status == 'blocked' end
|
|
12
12
|
def built_in?; status == 'system' end
|
13
13
|
def pending?; status == 'pending' end
|
14
14
|
|
15
|
-
def
|
15
|
+
def validate_token! test_token
|
16
16
|
tcard = token_card
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
left.id
|
21
|
-
else
|
22
|
-
error
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def token_error tcard, val
|
27
|
-
case
|
28
|
-
when !tcard
|
29
|
-
:token_not_found
|
30
|
-
when token != val
|
31
|
-
:incorrect_token
|
32
|
-
when tcard.updated_at <= Card.config.token_expiry.ago
|
33
|
-
# < means "before"
|
34
|
-
:token_expired
|
35
|
-
when !left || !left.accountable?
|
36
|
-
:illegal_account
|
37
|
-
else
|
38
|
-
:none
|
39
|
-
end
|
17
|
+
tcard.validate! test_token
|
18
|
+
copy_errors tcard
|
19
|
+
errors.empty?
|
40
20
|
end
|
41
21
|
|
42
22
|
format do
|
43
23
|
view :verify_url do
|
44
|
-
|
24
|
+
signup_name = card.cardname.left_name
|
25
|
+
card_url "update/#{signup_name.url_key}" \
|
26
|
+
"?token=#{card.token}" \
|
27
|
+
'&live_token=true'
|
45
28
|
end
|
46
29
|
|
47
30
|
view :verify_days do
|
@@ -49,8 +32,9 @@ format do
|
|
49
32
|
end
|
50
33
|
|
51
34
|
view :reset_password_url do
|
52
|
-
card_url "update/#{card.cardname.url_key}
|
53
|
-
"
|
35
|
+
card_url "update/#{card.cardname.url_key}" \
|
36
|
+
"?token=#{card.token_card.refresh(true).content}" \
|
37
|
+
'&live_token=true&event=reset_password'
|
54
38
|
end
|
55
39
|
|
56
40
|
view :reset_password_days do
|
@@ -76,20 +60,16 @@ format :html do
|
|
76
60
|
end
|
77
61
|
end
|
78
62
|
|
79
|
-
|
80
63
|
event :validate_accountability, on: :create, before: :approve do
|
81
|
-
unless left
|
82
|
-
errors.add :content,
|
64
|
+
unless left && left.accountable?
|
65
|
+
errors.add :content, 'not allowed on this card'
|
83
66
|
end
|
84
67
|
end
|
85
68
|
|
86
69
|
event :require_email, on: :create, after: :approve do
|
87
|
-
unless subfield(:email)
|
88
|
-
errors.add :email, 'required'
|
89
|
-
end
|
70
|
+
errors.add :email, 'required' unless subfield(:email)
|
90
71
|
end
|
91
72
|
|
92
|
-
|
93
73
|
event :set_default_salt, on: :create, before: :process_subcards do
|
94
74
|
salt = Digest::SHA1.hexdigest "--#{Time.now.to_s}--"
|
95
75
|
Env[:salt] = salt # HACK!!! need viable mechanism to get this to password
|
@@ -97,35 +77,34 @@ event :set_default_salt, on: :create, before: :process_subcards do
|
|
97
77
|
end
|
98
78
|
|
99
79
|
event :set_default_status, on: :create, before: :process_subcards do
|
100
|
-
default_status =
|
80
|
+
default_status = Auth.needs_setup? ? 'active' : 'pending'
|
101
81
|
add_subfield :status, content: default_status
|
102
82
|
end
|
103
83
|
|
104
84
|
def confirm_ok?
|
105
|
-
Card.new(
|
85
|
+
Card.new(type_id: Card.default_accounted_type_id).ok? :create
|
106
86
|
end
|
107
87
|
|
108
|
-
event :generate_confirmation_token,
|
88
|
+
event :generate_confirmation_token,
|
89
|
+
on: :create, before: :process_subcards,
|
90
|
+
when: proc { |c| c.confirm_ok? } do
|
109
91
|
add_subfield :token, content: generate_token
|
110
92
|
end
|
111
93
|
|
112
|
-
event :reset_password, on: :update, before: :approve, when:
|
113
|
-
|
114
|
-
|
115
|
-
|
94
|
+
event :reset_password, on: :update, before: :approve, when:
|
95
|
+
proc { |c| c.reset_password? } do
|
96
|
+
if validate_token! @env_token
|
97
|
+
token_card.used!
|
98
|
+
Auth.signin left_id
|
116
99
|
success << edit_password_success_args
|
117
|
-
abort :success
|
118
|
-
when :token_expired
|
119
|
-
send_reset_password_token
|
120
|
-
success << {
|
121
|
-
id: '_self',
|
122
|
-
view: 'message',
|
123
|
-
message: "Sorry, this token has expired. Please check your email for a new password reset link."
|
124
|
-
}
|
125
|
-
abort :success
|
126
100
|
else
|
127
|
-
|
101
|
+
error_msg = errors.first.last
|
102
|
+
send_reset_password_token
|
103
|
+
msg = "Sorry, #{error_msg}. " \
|
104
|
+
'Please check your email for a new password reset link.'
|
105
|
+
success << { id: '_self', view: 'message', message: msg }
|
128
106
|
end
|
107
|
+
abort :success
|
129
108
|
end
|
130
109
|
|
131
110
|
def edit_password_success_args
|
@@ -136,8 +115,9 @@ def edit_password_success_args
|
|
136
115
|
}
|
137
116
|
end
|
138
117
|
|
139
|
-
def
|
140
|
-
@env_token = Env.params[:
|
118
|
+
def reset_password?
|
119
|
+
@env_token = Env.params[:token]
|
120
|
+
@env_token && Env.params[:event] == 'reset_password'
|
141
121
|
end
|
142
122
|
|
143
123
|
event :reset_token do
|
@@ -146,55 +126,52 @@ event :reset_token do
|
|
146
126
|
end
|
147
127
|
end
|
148
128
|
|
149
|
-
|
150
129
|
event :send_welcome_email do
|
151
|
-
|
152
|
-
|
130
|
+
welcome = Card['welcome email']
|
131
|
+
if welcome && welcome.type_code == :email_template
|
132
|
+
welcome.deliver context: left, to: email
|
153
133
|
end
|
154
134
|
end
|
155
135
|
|
156
|
-
event :send_account_verification_email, on: :create, after: :extend, when:
|
157
|
-
|
136
|
+
event :send_account_verification_email, on: :create, after: :extend, when:
|
137
|
+
proc { |c| c.token.present? } do
|
138
|
+
Card[:verification_email].deliver context: self, to: email
|
158
139
|
end
|
159
140
|
|
160
141
|
event :send_reset_password_token do
|
161
142
|
Auth.as_bot do
|
162
143
|
token_card.update_attributes! content: generate_token
|
163
144
|
end
|
164
|
-
Card[:password_reset_email].deliver
|
145
|
+
Card[:password_reset_email].deliver context: self, to: email
|
165
146
|
end
|
166
147
|
|
167
148
|
def ok_to_read
|
168
149
|
is_own_account? ? true : super
|
169
150
|
end
|
170
151
|
|
171
|
-
|
172
152
|
def changes_visible? act
|
173
153
|
act.relevant_actions_for(act.card).each do |action|
|
174
154
|
return true if action.card.ok? :read
|
175
155
|
end
|
176
|
-
|
156
|
+
false
|
177
157
|
end
|
178
158
|
|
179
159
|
def send_change_notice act, followed_set, follow_option
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
end
|
160
|
+
return unless changes_visible?(act)
|
161
|
+
Auth.as(left.id) do
|
162
|
+
Card[:follower_notification_email].deliver(
|
163
|
+
context: act.card,
|
164
|
+
to: email,
|
165
|
+
follower: left.name,
|
166
|
+
followed_set: followed_set,
|
167
|
+
follow_option: follow_option
|
168
|
+
)
|
190
169
|
end
|
191
170
|
end
|
192
171
|
|
193
|
-
|
194
172
|
format :email do
|
195
173
|
view :mail do |args|
|
196
174
|
args[:to] ||= card.email
|
197
175
|
super args
|
198
176
|
end
|
199
177
|
end
|
200
|
-
|
@@ -1,5 +1,52 @@
|
|
1
1
|
include All::Permissions::Accounts
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
DURATIONS = 'second|minute|hour|day|week|month|year'
|
4
|
+
|
5
|
+
card_accessor :expiration
|
6
|
+
|
7
|
+
view :raw do
|
8
|
+
'Private data'
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate! token
|
12
|
+
error =
|
13
|
+
case
|
14
|
+
when !real? then [:token_not_found, 'no token found']
|
15
|
+
when expired? then [:token_expired, 'expired token']
|
16
|
+
when content != token then [:incorrect_token, 'token mismatch']
|
17
|
+
end
|
18
|
+
errors.add *error if error
|
19
|
+
end
|
20
|
+
|
21
|
+
def expired?
|
22
|
+
!permanent? && updated_at <= term.ago
|
23
|
+
end
|
24
|
+
|
25
|
+
def permanent?
|
26
|
+
term == 'permanent'
|
27
|
+
end
|
28
|
+
|
29
|
+
def used!
|
30
|
+
Auth.as_bot { delete! } unless permanent?
|
31
|
+
end
|
32
|
+
|
33
|
+
def term
|
34
|
+
@term ||=
|
35
|
+
if expiration.present?
|
36
|
+
term_from_string expiration
|
37
|
+
else
|
38
|
+
Card.config.token_expiry
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def term_from_string string
|
43
|
+
string.strip!
|
44
|
+
return 'permanent' if string == 'none'
|
45
|
+
re_match = /^(\d+)[\.\s]*(#{DURATIONS})s?$/.match(string)
|
46
|
+
number, unit = re_match.captures if re_match
|
47
|
+
if unit
|
48
|
+
number.to_i.send unit
|
49
|
+
else
|
50
|
+
raise Card::Oops, "illegal expiration value (eg '2 days')"
|
51
|
+
end
|
5
52
|
end
|
@@ -87,14 +87,14 @@ event :signin, before: :approve, on: :update do
|
|
87
87
|
|
88
88
|
abort :failure, 'bad signin args' unless email && pword
|
89
89
|
|
90
|
-
if (
|
91
|
-
Auth.signin
|
90
|
+
if (account = Auth.authenticate(email, pword))
|
91
|
+
Auth.signin account.left_id
|
92
92
|
else
|
93
|
-
|
93
|
+
account = Auth[email.strip.downcase]
|
94
94
|
error_msg =
|
95
95
|
case
|
96
|
-
when
|
97
|
-
when !
|
96
|
+
when account.nil? then 'Unrecognized email.'
|
97
|
+
when !account.active? then 'Sorry, that account is not active.'
|
98
98
|
else 'Wrong password'
|
99
99
|
end
|
100
100
|
errors.add :signin, error_msg
|
@@ -112,15 +112,17 @@ event :send_reset_password_token,
|
|
112
112
|
email = subfield :email
|
113
113
|
email &&= email.content
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
errors.add :account, 'not active'
|
115
|
+
account = Auth[email.strip.downcase]
|
116
|
+
if account
|
117
|
+
if account.active?
|
118
|
+
account.send_reset_password_token
|
119
|
+
abort :success
|
121
120
|
else
|
122
|
-
errors.add :
|
121
|
+
errors.add :account, 'not active'
|
122
|
+
abort :failure
|
123
123
|
end
|
124
|
+
else
|
125
|
+
errors.add :email, 'not recognized'
|
124
126
|
abort :failure
|
125
127
|
end
|
126
128
|
end
|
@@ -101,25 +101,21 @@ end
|
|
101
101
|
|
102
102
|
event :activate_by_token, before: :approve, on: :update,
|
103
103
|
when: proc { |c| c.has_token? } do
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
abort :failure, 'no field manipulation mid-activation' if subcards.present?
|
113
|
-
# necessary because the rest of the action is performed as Wagn Bot
|
104
|
+
abort :failure, 'no field manipulation mid-activation' if subcards.present?
|
105
|
+
# necessary because this performs actions as Wagn Bot
|
106
|
+
abort :failure, "no account associated with #{name}" if !account
|
107
|
+
|
108
|
+
account.validate_token! @env_token
|
109
|
+
|
110
|
+
if account.errors.empty?
|
111
|
+
account.token_card.used!
|
114
112
|
activate_account
|
115
113
|
Auth.signin id
|
116
|
-
Auth.as_bot
|
117
|
-
|
118
|
-
|
114
|
+
Auth.as_bot # use admin permissions for rest of action
|
115
|
+
success << ''
|
116
|
+
else
|
119
117
|
resend_activation_token
|
120
118
|
abort :success
|
121
|
-
else
|
122
|
-
abort :failure, "signup activation error: #{result}" # bad token or account
|
123
119
|
end
|
124
120
|
end
|
125
121
|
|
@@ -128,6 +124,7 @@ def has_token?
|
|
128
124
|
end
|
129
125
|
|
130
126
|
event :activate_account do
|
127
|
+
# FIXME: -- sends email before account is fully activated
|
131
128
|
add_subfield :account
|
132
129
|
subfield(:account).add_subfield :status, content: 'active'
|
133
130
|
self.type_id = Card.default_accounted_type_id
|
@@ -152,12 +149,11 @@ end
|
|
152
149
|
event :resend_activation_token do
|
153
150
|
account.reset_token
|
154
151
|
account.send_account_verification_email
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
}
|
152
|
+
message = 'Please check your email for a new password reset link.'
|
153
|
+
if account.errors.any?
|
154
|
+
message = "Sorry, #{account.errors.first.last}. #{message}"
|
155
|
+
end
|
156
|
+
success << { id: '_self', view: 'message', message: message }
|
161
157
|
end
|
162
158
|
|
163
159
|
def signed_in_as_me_without_password?
|
@@ -1,31 +1,45 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
3
|
describe Card::Set::Right::Account do
|
4
|
-
|
5
4
|
describe '#create' do
|
6
|
-
context
|
7
|
-
#note - much of this is tested in account_request_spec
|
5
|
+
context 'valid user' do
|
6
|
+
# note - much of this is tested in account_request_spec
|
8
7
|
before do
|
9
8
|
Card::Auth.as_bot do
|
10
|
-
@user_card = Card.create!
|
11
|
-
'
|
12
|
-
|
9
|
+
@user_card = Card.create!(
|
10
|
+
name: 'TmpUser',
|
11
|
+
type_id: Card::UserID,
|
12
|
+
'+*account' => {
|
13
|
+
'+*email' => 'tmpuser@wagn.org', '+*password' => 'tmp_pass'
|
14
|
+
}
|
15
|
+
)
|
13
16
|
end
|
14
|
-
|
15
17
|
end
|
16
18
|
|
17
19
|
it 'should create an authenticable password' do
|
18
|
-
|
20
|
+
validity = Card::Auth.password_valid? @user_card.account, 'tmp_pass'
|
21
|
+
expect(validity).to be_truthy
|
19
22
|
end
|
20
23
|
end
|
21
24
|
|
22
25
|
it "should check accountability of 'accounted' card" do
|
23
|
-
@unaccountable = Card.create
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
@unaccountable = Card.create(
|
27
|
+
name: 'BasicUnaccountable',
|
28
|
+
'+*account' => {
|
29
|
+
'+*email' => 'tmpuser@wagn.org',
|
30
|
+
'+*password' => 'tmp_pass'
|
31
|
+
}
|
32
|
+
)
|
33
|
+
error_msg = @unaccountable.errors['+*account'].first
|
34
|
+
expect(error_msg).to eq('not allowed on this card')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should require email' do
|
38
|
+
@no_email = Card.create(
|
39
|
+
name: 'TmpUser',
|
40
|
+
type_id: Card::UserID,
|
41
|
+
'+*account' => { '+*password' => 'tmp_pass' }
|
42
|
+
)
|
29
43
|
expect(@no_email.errors['+*account'].first).to match(/email required/)
|
30
44
|
end
|
31
45
|
end
|
@@ -33,78 +47,82 @@ describe Card::Set::Right::Account do
|
|
33
47
|
describe '#send_account_verification_email' do
|
34
48
|
before do
|
35
49
|
@email = 'joe@user.com'
|
36
|
-
@account = Card::Auth[@email]
|
50
|
+
@account = Card::Auth[@email]
|
37
51
|
Mail::TestMailer.deliveries.clear
|
38
52
|
@account.send_account_verification_email
|
39
53
|
@mail = Mail::TestMailer.deliveries.last
|
40
54
|
end
|
41
55
|
|
42
56
|
it 'has correct address' do
|
43
|
-
expect(
|
57
|
+
expect(@mail.to).to eq([@email])
|
44
58
|
end
|
45
59
|
|
46
60
|
it 'contains deck title' do
|
47
|
-
expect(
|
61
|
+
expect(@mail.parts[0].body.raw_source).to match(Card.setting(:title))
|
48
62
|
end
|
49
63
|
|
50
64
|
it 'contains link to verify account' do
|
51
|
-
|
65
|
+
url = "/update/#{@account.left.cardname.url_key}?token=#{@account.token}"
|
66
|
+
expect(@mail.parts[0].body.raw_source).to include(url)
|
52
67
|
end
|
53
68
|
|
54
69
|
it 'contains expiry days' do
|
55
|
-
|
70
|
+
msg = "valid for #{Card.config.token_expiry / 1.day} days"
|
71
|
+
expect(@mail.parts[0].body.raw_source).to include(msg)
|
56
72
|
end
|
57
73
|
end
|
58
74
|
|
59
75
|
describe '#send_reset_password_token' do
|
60
76
|
before do
|
61
77
|
@email = 'joe@user.com'
|
62
|
-
@account = Card::Auth[@email]
|
78
|
+
@account = Card::Auth[@email]
|
63
79
|
Mail::TestMailer.deliveries = []
|
64
80
|
@account.send_reset_password_token
|
65
81
|
@mail = Mail::TestMailer.deliveries.last
|
66
82
|
end
|
67
83
|
|
68
84
|
it 'contains deck title' do
|
69
|
-
expect(
|
85
|
+
expect(@mail.parts[0].body.raw_source).to match(Card.setting(:title))
|
70
86
|
end
|
71
87
|
|
72
88
|
it 'contains password resset link' do
|
73
|
-
|
89
|
+
token = @account.token_card.refresh(true).content
|
90
|
+
url = "/update/#{@account.cardname.url_key}?token=#{token}"
|
91
|
+
expect(@mail.parts[0].body.raw_source).to include(url)
|
74
92
|
end
|
75
93
|
|
76
94
|
it 'contains expiry days' do
|
77
|
-
|
95
|
+
url = "valid for #{Card.config.token_expiry / 1.day} days"
|
96
|
+
expect(@mail.parts[0].body.raw_source).to include(url)
|
78
97
|
end
|
79
98
|
end
|
80
99
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
100
|
describe '#update_attributes' do
|
85
101
|
before :each do
|
86
|
-
@
|
102
|
+
@account = Card::Auth['joe@user.com']
|
87
103
|
end
|
88
104
|
|
89
105
|
it 'should reset password' do
|
90
|
-
@
|
91
|
-
|
106
|
+
@account.password_card.update_attributes!(content: 'new password')
|
107
|
+
authenticated = Card::Auth.authenticate 'joe@user.com', 'new password'
|
108
|
+
assert_equal @account, authenticated
|
92
109
|
end
|
93
110
|
|
94
111
|
it 'should not rehash password when updating email' do
|
95
|
-
@
|
96
|
-
|
112
|
+
@account.email_card.update_attributes! content: 'joe2@user.com'
|
113
|
+
authenticated = Card::Auth.authenticate 'joe2@user.com', 'joe_pass'
|
114
|
+
assert_equal @account, authenticated
|
97
115
|
end
|
98
116
|
end
|
99
117
|
|
100
|
-
|
101
118
|
describe '#reset_password' do
|
102
119
|
before :each do
|
103
120
|
@email = 'joe@user.com'
|
104
|
-
@account = Card::Auth[@email]
|
121
|
+
@account = Card::Auth[@email]
|
105
122
|
@account.send_reset_password_token
|
106
123
|
@token = @account.token
|
107
|
-
Card::Env.params[:
|
124
|
+
Card::Env.params[:token] = @token
|
125
|
+
Card::Env.params[:event] = 'reset_password'
|
108
126
|
Card::Auth.current_id = Card::AnonymousID
|
109
127
|
end
|
110
128
|
|
@@ -112,44 +130,51 @@ describe Card::Set::Right::Account do
|
|
112
130
|
expect(Card::Auth.current_id).to eq(Card::AnonymousID)
|
113
131
|
expect(@account.save).to eq(true)
|
114
132
|
expect(Card::Auth.current_id).to eq(@account.left_id)
|
115
|
-
@account = @account.refresh
|
133
|
+
@account = @account.refresh true
|
116
134
|
expect(@account.fetch(trait: :token)).to be_nil
|
117
|
-
expect(@account.save).to be_falsey
|
118
135
|
end
|
119
136
|
|
120
137
|
it 'should not work if token is expired' do
|
121
|
-
@account.token_card.update_column :updated_at,
|
138
|
+
@account.token_card.update_column :updated_at,
|
139
|
+
3.days.ago.strftime('%F %T')
|
122
140
|
@account.token_card.expire
|
123
|
-
|
124
141
|
result = @account.save
|
125
|
-
|
126
|
-
expect(
|
127
|
-
|
142
|
+
|
143
|
+
expect(result).to eq(true)
|
144
|
+
# successfully completes save
|
145
|
+
|
146
|
+
expect(@account.token).not_to eq(@token)
|
147
|
+
# token gets updated
|
148
|
+
|
149
|
+
expect(@account.success.message).to match(/expired/)
|
150
|
+
# user notified of expired token
|
128
151
|
end
|
129
152
|
|
130
153
|
it 'should not work if token is wrong' do
|
131
|
-
Card::Env.params[:
|
154
|
+
Card::Env.params[:token] = @token + 'xxx'
|
155
|
+
Card::Env.params[:event] = 'reset_password'
|
132
156
|
@account.save
|
133
|
-
expect(@account.errors[:
|
157
|
+
expect(@account.errors[:incorrect_token].first).to match(/mismatch/)
|
134
158
|
end
|
135
|
-
|
136
159
|
end
|
137
160
|
|
138
|
-
|
139
161
|
describe '#send_change_notice' do
|
140
162
|
it 'send multipart email' do
|
141
163
|
skip
|
142
|
-
# pending
|
164
|
+
# pending
|
143
165
|
end
|
144
166
|
|
145
167
|
context 'denied access' do
|
146
168
|
it 'excludes protected subcards' do
|
147
169
|
skip
|
148
|
-
Card.create(name:
|
149
|
-
|
150
|
-
u2.
|
151
|
-
|
152
|
-
|
170
|
+
Card.create(name: 'A+B+*self+*read', type: 'Pointer', content: '[[u1]]')
|
171
|
+
|
172
|
+
u2 = Card.fetch 'u2+*following', new: { type: 'Pointer' }
|
173
|
+
u2.add_item 'A'
|
174
|
+
|
175
|
+
a = Card.fetch 'A'
|
176
|
+
a.update_attributes(content: 'new content',
|
177
|
+
subcards: { '+B' => { content: 'hidden content' } })
|
153
178
|
end
|
154
179
|
|
155
180
|
it 'sends no email if changes not visible' do
|
@@ -158,4 +183,3 @@ describe Card::Set::Right::Account do
|
|
158
183
|
end
|
159
184
|
end
|
160
185
|
end
|
161
|
-
|