card 1.96.0 → 1.96.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/initializers/02_patches/kaminari.rb +2 -2
  4. data/config/locales/de.yml +38 -3
  5. data/config/locales/en.yml +39 -4
  6. data/config/locales/es.yml +606 -0
  7. data/db/migrate_core_cards/data/cards/{*header → Xheader} +0 -0
  8. data/db/migrate_core_cards/data/cards/{*main_menu → Xmain_menu} +0 -0
  9. data/lib/card.rb +2 -2
  10. data/lib/card/act_manager.rb +1 -1
  11. data/lib/card/env/success.rb +26 -13
  12. data/lib/card/format/nest/fetch.rb +6 -1
  13. data/lib/card/migration/import/import_data/card_content.rb +1 -1
  14. data/mod/account/set/right/account.rb +115 -101
  15. data/mod/account/set/self/signin.rb +106 -96
  16. data/mod/account/spec/set/all/account_spec.rb +0 -2
  17. data/mod/account/spec/set/right/account_spec.rb +6 -9
  18. data/mod/account/spec/set/self/signin_spec.rb +2 -5
  19. data/mod/admin/set/self/admin_info.rb +4 -4
  20. data/mod/admin/spec/set/self/admin_info_spec.rb +10 -0
  21. data/mod/admin/spec/set/self/trash_spec.rb +7 -0
  22. data/mod/basic_formats/set/all/json.rb +7 -3
  23. data/mod/basic_formats/spec/set/all/head_spec.rb +33 -0
  24. data/mod/basic_types/set/type/json.rb +1 -1
  25. data/mod/basic_types/spec/set/type/plain_text_spec.rb +6 -0
  26. data/mod/bootstrap/set/type/customized_bootswatch_skin.rb +2 -2
  27. data/mod/bootstrap/spec/set/type/customized_bootswatch_skin/html_views_spec.rb +5 -0
  28. data/mod/bootstrap/spec/set/type_plus_right/customized_bootswatch_skin/colors_spec.rb +8 -0
  29. data/mod/carrierwave/set/abstract/attachment/storage_type.rb +12 -13
  30. data/mod/core/set/all/actify.rb +5 -0
  31. data/mod/core/set/all/codename.rb +2 -2
  32. data/mod/core/set/all/event_conditions.rb +2 -1
  33. data/mod/core/set/all/fetch_helper.rb +2 -2
  34. data/mod/core/set/all/i18n.rb +1 -1
  35. data/mod/core/set/all/item.rb +6 -0
  36. data/mod/core/set/all/location_history.rb +12 -1
  37. data/mod/core/set/all/name_events.rb +8 -9
  38. data/mod/core/set/all/permissions.rb +1 -1
  39. data/mod/core/set/all/rename.rb +3 -5
  40. data/mod/core/set/all/trash.rb +4 -9
  41. data/mod/core/set/all/type.rb +7 -5
  42. data/mod/core/set/all/utils.rb +13 -5
  43. data/mod/core/spec/set/abstract/code_file_spec.rb +8 -0
  44. data/mod/core/spec/set/all/tabs_spec.rb +19 -0
  45. data/mod/developer/spec/set/all/view_viz_spec.rb +9 -0
  46. data/mod/follow/spec/set/all/follow/follow_link_spec.rb +7 -0
  47. data/mod/follow/spec/set/all/notify/html_views_spec.rb +7 -0
  48. data/mod/follow/spec/set/right/follow_spec.rb +0 -0
  49. data/mod/follow/spec/set/right/following_spec.rb +6 -0
  50. data/mod/follow/spec/set/type/notification_template_spec.rb +1 -1
  51. data/mod/history/set/all/content_history.rb +1 -1
  52. data/mod/history/spec/set/all/act_view_spec.rb +16 -0
  53. data/mod/history/spec/set/all/action_view_spec.rb +10 -0
  54. data/mod/history/spec/set/all/history_spec.rb +11 -0
  55. data/mod/item/spec/set/all/bar_spec.rb +41 -0
  56. data/mod/machines/lib/javascript/decko_slot.js.coffee +1 -1
  57. data/mod/pointer/set/abstract/02_pointer/other_views.rb +0 -4
  58. data/mod/recaptcha/set/all/recaptcha.rb +1 -1
  59. data/mod/search/spec/set/abstract/search_spec.rb +8 -0
  60. data/mod/standard/set/all/error.rb +48 -26
  61. data/mod/standard/set/all/rich_html/toolbar.rb +6 -1
  62. data/mod/standard/set/type/list.rb +7 -9
  63. data/mod/standard/set/type/number.rb +1 -1
  64. data/mod/standard/set/type/session.rb +1 -1
  65. data/mod/standard/spec/content/chunk/link_spec.rb +3 -3
  66. data/mod/utility/set/abstract/media.rb +13 -9
  67. data/mod/utility/set/abstract/media/media_snippet.haml +5 -3
  68. metadata +22 -6
@@ -144,9 +144,9 @@ class Card < ApplicationRecord
144
144
  :only_storage_phase, # used to save subcards
145
145
  :changed_attributes,
146
146
  :skip, # skip event(s) for all cards in act
147
- :skip_in_action, # skip event for just this card
147
+ :skip_in_action, # skip event for just this card
148
148
  :trigger, # trigger event(s) for all cards in act
149
- :trigger_in_action # trigger event for just this card
149
+ :trigger_in_action # trigger event for just this card
150
150
  )
151
151
 
152
152
  alias_method :skip_event, :skip
@@ -169,7 +169,7 @@ class Card
169
169
  # controller's params hash and the Card::Env's params hash with the
170
170
  # effect that params changes in the CardController get lost
171
171
  # (a crucial example are success params that are processed in
172
- # CardController#update_params_for_success)
172
+ # CardController#soft_redirect)
173
173
  def contextualize_delayed_event act_id, card, env, auth
174
174
  if delaying?
175
175
  contextualize_for_delay(act_id, card, env, auth) { yield }
@@ -1,28 +1,40 @@
1
1
  class Card
2
2
  module Env
3
+ # Success objects
3
4
  class Success
4
5
  include Card::Env::Location
5
6
 
6
7
  attr_accessor :params, :redirect, :id, :name, :card, :name_context
7
8
 
8
- def initialize name_context=nil, success_params=nil
9
+ def initialize name_context=nil, success_args=nil
9
10
  @name_context = name_context
10
11
  @new_args = {}
11
12
  @params = OpenStruct.new
12
- case success_params
13
- when Hash
14
- apply(success_params)
13
+ self << normalize_success_args(success_args)
14
+ end
15
+
16
+ def in_context name_context
17
+ self.name_context = name_context
18
+ self
19
+ end
20
+
21
+ def normalize_success_args success_args
22
+ case success_args
23
+ when nil
24
+ self.mark = "_self"
25
+ {}
15
26
  when ActionController::Parameters
16
- apply(success_params.to_unsafe_h)
17
- when nil then self.name = "_self"
18
- else; self.target = success_params
27
+ success_args.to_unsafe_h
28
+ else
29
+ success_args
19
30
  end
20
31
  end
21
32
 
22
33
  def << value
23
- case value
24
- when Hash then apply value
25
- else; self.target = value
34
+ if value.is_a? Hash
35
+ apply value
36
+ else
37
+ self.target = value
26
38
  end
27
39
  end
28
40
 
@@ -35,6 +47,7 @@ class Card
35
47
  @redirect == :soft
36
48
  end
37
49
 
50
+ # TODO: refactor to use cardish
38
51
  def mark= value
39
52
  case value
40
53
  when Integer then @id = value
@@ -45,6 +58,7 @@ class Card
45
58
  end
46
59
  end
47
60
 
61
+ # @deprecated
48
62
  def id= id
49
63
  # for backwards compatibility use mark here.
50
64
  # id was often used for the card name
@@ -73,7 +87,6 @@ class Card
73
87
  when "" then ""
74
88
  when "*previous", :previous then :previous
75
89
  when %r{^(http|/)} then value
76
- when /^TEXT:\s*(.+)/ then Regexp.last_match(1)
77
90
  when /^REDIRECT:\s*(.+)/
78
91
  @redirect = true
79
92
  process_target Regexp.last_match(1)
@@ -81,8 +94,8 @@ class Card
81
94
  end
82
95
  end
83
96
 
84
- def apply args
85
- args.each_pair do |key, value|
97
+ def apply hash
98
+ hash.each_pair do |key, value|
86
99
  self[key] = value
87
100
  end
88
101
  end
@@ -19,10 +19,15 @@ class Card
19
19
  def not_found_codename cardish
20
20
  @view = :not_found
21
21
  c = Card.new name: Array.wrap(cardish).join(Card::Name.joint).to_s
22
- c.errors.add :codename, "unknown codename in #{cardish}"
22
+ c.errors.add :codename, not_found_codename_error(cardish)
23
23
  c
24
24
  end
25
25
 
26
+ def not_found_codename_error codename
27
+ ::I18n.t :exception_unknown_codename, codename: codename,
28
+ scope: "lib.card.codename"
29
+ end
30
+
26
31
  def new_card cardish
27
32
  view_opts[:nest_name] = Card::Name[cardish].to_s
28
33
  Card.fetch cardish, new: new_card_args
@@ -20,7 +20,7 @@ class Card
20
20
  end
21
21
 
22
22
  def content_path data
23
- filename = data[:key] || data[:name].to_name.key
23
+ filename = (data[:key] || data[:name]).to_name.safe_key
24
24
  File.join @card_content_dir, filename
25
25
  end
26
26
  end
@@ -8,6 +8,68 @@ card_accessor :salt
8
8
  card_accessor :status
9
9
  card_accessor :token
10
10
 
11
+ #### ON CREATE
12
+
13
+ # legal to add +*account card
14
+ event :validate_accountability, :prepare_to_validate, on: :create do
15
+ errors.add :content, tr(:error_not_allowed) unless left&.accountable?
16
+ end
17
+
18
+ event :require_email, :prepare_to_validate,
19
+ after: :validate_accountability, on: :create do
20
+ errors.add :email, "required" unless subfield(:email)
21
+ end
22
+
23
+ event :set_default_salt, :prepare_to_validate, on: :create do
24
+ salt = Digest::SHA1.hexdigest "--#{Time.zone.now}--"
25
+ Env[:salt] = salt # HACK!!! need viable mechanism to get this to password
26
+ add_subfield :salt, content: salt
27
+ end
28
+
29
+ event :set_default_status, :prepare_to_validate, on: :create do
30
+ default_status = Auth.needs_setup? ? "active" : "pending"
31
+ add_subfield :status, content: default_status
32
+ end
33
+
34
+ event :generate_confirmation_token,
35
+ :prepare_to_store, on: :create, when: :can_approve? do
36
+ add_subfield :token, content: generate_token
37
+ end
38
+
39
+ event :send_account_verification_email, :integrate,
40
+ on: :create, when: proc { |c| c.token.present? } do
41
+ Card[:verification_email].deliver self, to: email
42
+ end
43
+
44
+ # ON UPDATE
45
+
46
+ # reset password emails contain a link to update the +*account card
47
+ # and trigger this event
48
+ event :reset_password, :prepare_to_validate, on: :update, trigger: :required do
49
+ reset_password_with_token Env.params[:token]
50
+ end
51
+
52
+ # STANDALONE EVENTS
53
+ # only triggered when called directly (as methods)
54
+
55
+ event :reset_token do
56
+ token = generate_token
57
+ Auth.as_bot { token_card.update_attributes! content: token }
58
+ token
59
+ end
60
+
61
+ event :send_welcome_email do
62
+ welcome = Card[:welcome_email]
63
+ welcome.deliver self, to: email if welcome&.type_code == :email_template
64
+ end
65
+
66
+ event :send_reset_password_token do
67
+ Auth.as_bot do
68
+ token_card.update_attributes! content: generate_token
69
+ end
70
+ Card[:password_reset_email].deliver self, to: email
71
+ end
72
+
11
73
  def active?
12
74
  status == "active"
13
75
  end
@@ -31,6 +93,19 @@ def validate_token! test_token
31
93
  errors.empty?
32
94
  end
33
95
 
96
+ def reset_password_with_token token
97
+ aborting do
98
+ if !token
99
+ errors.add :token, "is required"
100
+ elsif !validate_token!(token)
101
+ # FIXME: isn't this an error??
102
+ success << reset_password_try_again
103
+ else
104
+ success << reset_password_success
105
+ end
106
+ end
107
+ end
108
+
34
109
  def refreshed_token
35
110
  if token_card.id
36
111
  token_card.refresh(true).db_content # TODO: explain why refresh is needed
@@ -39,9 +114,43 @@ def refreshed_token
39
114
  end
40
115
  end
41
116
 
117
+ def can_approve?
118
+ Card.new(type_id: Card.default_accounted_type_id).ok? :create
119
+ end
120
+
121
+ def ok_to_read
122
+ own_account? ? true : super
123
+ end
124
+
125
+ def reset_password_success
126
+ token_card.used!
127
+ Auth.signin left_id
128
+ { id: left.name,
129
+ view: :related,
130
+ slot: { items: { nest_name: :account.cardname.prepend_joint,
131
+ view: :edit } } }
132
+ end
133
+
134
+ def reset_password_try_again
135
+ send_reset_password_token
136
+ { id: "_self",
137
+ view: "message",
138
+ message: tr(:sorry_email_reset, error_msg: errors.first.last) }
139
+ end
140
+
141
+ # FIXME: explain or remove.
142
+ def edit_password_success_args; end
143
+
144
+ def changes_visible? act
145
+ act.actions_affecting(act.card).each do |action|
146
+ return true if action.card.ok? :read
147
+ end
148
+ false
149
+ end
150
+
42
151
  format do
43
152
  view :verify_url, cache: :never do
44
- card_url path({ mark: card.name.left }.merge(token_path_opts))
153
+ card_url path(token_path_opts.merge(mark: card.name.left))
45
154
  end
46
155
 
47
156
  view :verify_days, cache: :never do
@@ -49,16 +158,16 @@ format do
49
158
  end
50
159
 
51
160
  view :reset_password_url do
52
- card_url path({ mark: card, event: :reset_password }.merge(token_path_opts))
53
- end
54
-
55
- def token_path_opts
56
- { action: :update, live_token: true, token: card.refreshed_token }
161
+ card_url path(token_path_opts.merge(card: { trigger: :reset_password }))
57
162
  end
58
163
 
59
164
  view :reset_password_days do
60
165
  (Card.config.token_expiry / 1.day).to_s
61
166
  end
167
+
168
+ def token_path_opts
169
+ { action: :update, live_token: true, token: card.refreshed_token }
170
+ end
62
171
  end
63
172
 
64
173
  format :html do
@@ -84,101 +193,6 @@ format :html do
84
193
  end
85
194
  end
86
195
 
87
- event :validate_accountability, :prepare_to_validate, on: :create do
88
- unless left && left.accountable?
89
- errors.add :content, tr(:error_not_allowed)
90
- end
91
- end
92
-
93
- event :require_email, :prepare_to_validate,
94
- after: :validate_accountability, on: :create do
95
- errors.add :email, "required" unless subfield(:email)
96
- end
97
-
98
- event :set_default_salt, :prepare_to_validate, on: :create do
99
- salt = Digest::SHA1.hexdigest "--#{Time.zone.now}--"
100
- Env[:salt] = salt # HACK!!! need viable mechanism to get this to password
101
- add_subfield :salt, content: salt
102
- end
103
-
104
- event :set_default_status, :prepare_to_validate, on: :create do
105
- default_status = Auth.needs_setup? ? "active" : "pending"
106
- add_subfield :status, content: default_status
107
- end
108
-
109
- def can_approve?
110
- Card.new(type_id: Card.default_accounted_type_id).ok? :create
111
- end
112
-
113
- event :generate_confirmation_token,
114
- :prepare_to_store, on: :create, when: :can_approve? do
115
- add_subfield :token, content: generate_token
116
- end
117
-
118
- event :reset_password,
119
- :prepare_to_validate, on: :update, when: :reset_password? do
120
- valid = validate_token! @env_token
121
- success << (valid ? reset_password_success : reset_password_try_again)
122
- abort :success
123
- end
124
-
125
- def reset_password_success
126
- token_card.used!
127
- Auth.signin left_id
128
- { id: left.name,
129
- view: :related,
130
- slot: { items: { nest_name: :account.cardname.prepend_joint,
131
- view: :edit } } }
132
- end
133
-
134
- def reset_password_try_again
135
- send_reset_password_token
136
- { id: "_self",
137
- view: "message",
138
- message: tr(:sorry_email_reset, error_msg: errors.first.last) }
139
- end
140
-
141
- def edit_password_success_args; end
142
-
143
- def reset_password?
144
- @env_token = Env.params[:token]
145
- @env_token && Env.params[:event] == "reset_password"
146
- end
147
-
148
- event :reset_token do
149
- Auth.as_bot do
150
- token_card.update_attributes! content: generate_token
151
- end
152
- end
153
-
154
- event :send_welcome_email do
155
- welcome = Card[:welcome_email]
156
- welcome.deliver self, to: email if welcome&.type_code == :email_template
157
- end
158
-
159
- event :send_account_verification_email, :integrate,
160
- on: :create, when: proc { |c| c.token.present? } do
161
- Card[:verification_email].deliver self, to: email
162
- end
163
-
164
- event :send_reset_password_token do
165
- Auth.as_bot do
166
- token_card.update_attributes! content: generate_token
167
- end
168
- Card[:password_reset_email].deliver self, to: email
169
- end
170
-
171
- def ok_to_read
172
- own_account? ? true : super
173
- end
174
-
175
- def changes_visible? act
176
- act.actions_affecting(act.card).each do |action|
177
- return true if action.card.ok? :read
178
- end
179
- false
180
- end
181
-
182
196
  format :email do
183
197
  def mail context, fields
184
198
  super context, fields.reverse_merge(to: card.email)
@@ -1,8 +1,93 @@
1
+
2
+ # The Sign In card manages logging in and out of the site.
3
+ #
4
+ # /:signin (core view) gives the login ui
5
+ # /:signin?view=edit gives the forgot password ui
6
+
7
+ # /update/:signin is the login action
8
+ # /delete/:signin is the logout action
9
+
10
+ # authentication event
11
+ event :signin, :validate, on: :update do
12
+ email = subfield :email
13
+ email &&= email.content
14
+ pword = subfield :password
15
+ pword &&= pword.content
16
+
17
+ authenticate_or_abort email, pword
18
+ end
19
+
20
+ # abort after successful signin (do not save card)
21
+ event :signin_success, after: :signin do
22
+ abort :success
23
+ end
24
+
25
+ event :signout, :validate, on: :delete do
26
+ Auth.signin nil
27
+ abort :success
28
+ end
29
+
30
+ # triggered by clicking "Reset my Password", this sends out the verification password
31
+ # and aborts (does not sign in)
32
+ event :send_reset_password_token, before: :signin, on: :update, trigger: :required do
33
+ email = subfield(:email)&.content
34
+ account = Auth.find_account_by_email email
35
+ send_reset_password_email_or_fail account
36
+ end
37
+
1
38
  def consider_recaptcha?
2
39
  false
3
40
  end
4
41
 
42
+ def i18n_signin key
43
+ I18n.t key, scope: "mod.account.set.self.signin"
44
+ end
45
+
46
+ def authenticate_or_abort email, pword
47
+ abort :failure, i18n_signin(:abort_bad_signin_args) unless email && pword
48
+ if (account = Auth.authenticate(email, pword))
49
+ Auth.signin account.left_id
50
+ else
51
+ account = Auth.find_account_by_email email
52
+ errors.add :signin, signin_error_message(account)
53
+ abort :failure
54
+ end
55
+ end
56
+
57
+ def signin_error_message account
58
+ case
59
+ when account.nil? then i18n_signin(:error_unknown_email)
60
+ when !account.active? then i18n_signin(:error_not_active)
61
+ else i18n_signin(:error_wrong_password)
62
+ end
63
+ end
64
+
65
+ def send_reset_password_email_or_fail account
66
+ aborting do
67
+ if account && account.active?
68
+ account.send_reset_password_token
69
+ elsif account
70
+ errors.add :account, i18n_signin(:error_not_active)
71
+ else
72
+ errors.add :email, i18n_signin(:error_not_recognized)
73
+ end
74
+ end
75
+ end
76
+
5
77
  format :html do
78
+ view :core, cache: :never do
79
+ voo.edit_structure = [signin_field(:email), signin_field(:password)]
80
+ with_nest_mode :edit do
81
+ card_form :update, recaptcha: :off do
82
+ [
83
+ hidden_signin_fields,
84
+ _render_content_formgroup,
85
+ _render_signin_buttons
86
+ ]
87
+ end
88
+ end
89
+ end
90
+
6
91
  view :open do
7
92
  voo.show :help
8
93
  super()
@@ -23,21 +108,9 @@ format :html do
23
108
  ""
24
109
  end
25
110
 
26
- view :core, cache: :never do
27
- voo.edit_structure = [signin_field(:email), signin_field(:password)]
28
- with_nest_mode :edit do
29
- card_form :update, recaptcha: :off do
30
- [
31
- hidden_signin_fields,
32
- _render_content_formgroup,
33
- _render_signin_buttons
34
- ]
35
- end
36
- end
37
- end
38
-
39
- def hidden_signin_fields
40
- hidden_field_tag :success, "REDIRECT: #{Env.interrupted_action || '*previous'}"
111
+ view :reset_password_success do
112
+ # 'Check your email for a link to reset your password'
113
+ frame { I18n.t(:check_email, scope: "mod.account.set.self.signin") }
41
114
  end
42
115
 
43
116
  view :signin_buttons do
@@ -46,6 +119,23 @@ format :html do
46
119
  end
47
120
  end
48
121
 
122
+ # FORGOT PASSWORD
123
+ view :edit do
124
+ voo.title ||= card.i18n_signin(:forgot_password)
125
+ voo.edit_structure = [signin_field(:email)]
126
+ voo.hide :help
127
+ Auth.as_bot { super() }
128
+ end
129
+
130
+ view :edit_buttons do
131
+ text = I18n.t :reset_my_password, scope: "mod.account.set.self.signin"
132
+ button_tag text, situation: "primary"
133
+ end
134
+
135
+ def hidden_signin_fields
136
+ hidden_field_tag :success, "REDIRECT: #{Env.interrupted_action || '*previous'}"
137
+ end
138
+
49
139
  def signin_button
50
140
  text = I18n.t :sign_in, scope: "mod.account.set.self.signin"
51
141
  button_tag text, situation: "primary"
@@ -63,96 +153,16 @@ format :html do
63
153
  raw("<div style='float:right'>#{reset_link}</div>")
64
154
  end
65
155
 
66
- # FORGOT PASSWORD
67
- view :edit do
68
- voo.title ||= card.i18n_signin(:forgot_password)
69
- voo.edit_structure = [signin_field(:email)]
70
- voo.hide :help
71
- Auth.as_bot { super() }
72
- end
73
-
74
156
  def edit_view_hidden
75
157
  hidden_tags(
76
- reset_password: true,
158
+ card: { trigger: :send_reset_password_token },
77
159
  success: { view: :reset_password_success }
78
160
  )
79
161
  end
80
162
 
81
- view :edit_buttons do
82
- text = I18n.t :reset_my_password, scope: "mod.account.set.self.signin"
83
- button_tag text, situation: "primary"
84
- end
85
-
86
163
  def signin_field name
87
164
  nest_name = "".to_name.trait(name)
88
165
  [nest_name, { title: name.to_s, view: "titled",
89
166
  nest_name: nest_name, skip_perms: true }]
90
167
  end
91
-
92
- view :reset_password_success do
93
- # 'Check your email for a link to reset your password'
94
- frame { I18n.t(:check_email, scope: "mod.account.set.self.signin") }
95
- end
96
- end
97
-
98
- event :signin, :validate, on: :update do
99
- email = subfield :email
100
- email &&= email.content
101
- pword = subfield :password
102
- pword &&= pword.content
103
-
104
- authenticate_or_abort email, pword
105
- end
106
-
107
- def authenticate_or_abort email, pword
108
- abort :failure, i18n_signin(:abort_bad_signin_args) unless email && pword
109
- if (account = Auth.authenticate(email, pword))
110
- Auth.signin account.left_id
111
- else
112
- account = Auth.find_account_by_email email
113
- errors.add :signin, signin_error_message(account)
114
- abort :failure
115
- end
116
- end
117
-
118
- def signin_error_message account
119
- case
120
- when account.nil? then i18n_signin(:error_unknown_email)
121
- when !account.active? then i18n_signin(:error_not_active)
122
- else i18n_signin(:error_wrong_password)
123
- end
124
- end
125
-
126
- def i18n_signin key
127
- I18n.t key, scope: "mod.account.set.self.signin"
128
- end
129
-
130
- event :signin_success, after: :signin do
131
- abort :success
132
- end
133
-
134
- event :send_reset_password_token, before: :signin, on: :update,
135
- when: proc { Env.params[:reset_password] } do
136
- email = subfield :email
137
- email &&= email.content
138
-
139
- account = Auth.find_account_by_email email
140
- send_reset_password_email_or_fail account
141
- end
142
-
143
- def send_reset_password_email_or_fail account
144
- if account && account.active?
145
- account.send_reset_password_token
146
- abort :success
147
- elsif account
148
- errors.add :account, i18n_signin(:error_not_active)
149
- else
150
- errors.add :email, i18n_signin(:error_not_recognized)
151
- end
152
- abort :failure
153
- end
154
-
155
- event :signout, :validate, on: :delete do
156
- Auth.signin nil
157
- abort :success
158
168
  end