card-mod-account 0.18.1 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ba05840b147403c0678e4db3ac24db0189bedcd608b796acabe14508fe1ec21
4
- data.tar.gz: 55985598054e74c33849c9fe582b7d129de544b35ea1dffa8ee0a945c4cb981f
3
+ metadata.gz: 8b847da022a51049cbedb208cdbf6e07c360ac3890423da3febe69fb74ab774a
4
+ data.tar.gz: '08826c58b6d56c7b0eea32ac818c09c80ac38b8cf2adad41ebf261dc92132673'
5
5
  SHA512:
6
- metadata.gz: 4e43112b506e88693cfc28b9a27f9895262c23cd3db7665704717636db17d572059c15f8fd46a26512efb23a193e704ba15d69e37ff75c3254ca8b8f4bd1796e
7
- data.tar.gz: ad7d881bd0ab9f5b2695f14cd86ae3171b2b8551353d0258c2a8db6416651985f14c2601e303886f9098de3e7732eac0ed6f587231c1da4b36ce00fd45dafdbc
6
+ metadata.gz: 7078a10e89e7b77589a6c2d6931cf96a9c54dac3e613c23929947dd4a6d0d53f40828855c23ac047ba3b58245122ff9d959ed736a8310a0054d8d9a12e32d187
7
+ data.tar.gz: ae2d62aa81290024ddad55494182eb50d583b30ebc599d5fdbec85ba91148757cf23a9d937c08b6828f69a84c4173ceecd047b58e3d7185c86081344a1d52636
@@ -32,5 +32,9 @@ en:
32
32
  account_sign_in_title: Sign In
33
33
  account_sign_out: Sign out
34
34
  account_sign_up: Sign up
35
+ account_close_account: Permanently Close Account
36
+ account_confirm_delete_account:
37
+ Are you CERTAIN you want to PERMANENTLY delete the account associated
38
+ with %{accounted}?
35
39
  account_sorry_email_reset:
36
40
  Sorry, %{error_msg}. Please check your email for a new password reset link.
@@ -42,6 +42,7 @@ class MoveRoles < Cardio::Migration::Transform
42
42
  .exec_query(query)
43
43
  .rows&.first&.first
44
44
  return unless content.present?
45
+
45
46
  content.split "\n"
46
47
  end
47
48
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  class MemberIds < Cardio::Migration::Transform
4
4
  def up
5
- Card.search(right: :members).each &:save!
5
+ Card.search(right: :members).each(&:save!)
6
6
  end
7
7
  end
@@ -72,8 +72,22 @@ def account_manager?
72
72
  own_account? || parties.member?(HelpDeskID)
73
73
  end
74
74
 
75
+ def close_account
76
+ anonymize!
77
+ closure_deletions.each(&:delete)
78
+ self
79
+ end
80
+
75
81
  private
76
82
 
83
+ def anonymize!
84
+ self.name = "ANON-#{SecureRandom.hex(6)}"
85
+ end
86
+
87
+ def closure_deletions
88
+ Card::Auth.as_bot { Card.search left: id, not: { right: :account } }
89
+ end
90
+
77
91
  def enabled_role_ids
78
92
  with_enabled_roles do |enabled|
79
93
  enabled.virtual? ? enabled.item_ids : fetch_roles
@@ -109,6 +123,8 @@ def fetch_read_rules
109
123
  end
110
124
 
111
125
  format :html do
126
+ view :closed_account, template: :haml
127
+
112
128
  def default_board_tab
113
129
  card.current_account? ? :account_tab : super
114
130
  end
@@ -141,7 +157,9 @@ format :html do
141
157
  ["API", :account,
142
158
  { path: { view: :api_key,
143
159
  items: { view: :content },
144
- slot: { hide: %i[help_link board_link] } } }]
160
+ slot: { hide: %i[help_link board_link] } } }],
161
+ ["Close Account", :account,
162
+ { path: { view: :closure } }]
145
163
  ]
146
164
  end
147
165
 
@@ -0,0 +1,5 @@
1
+ %h2 Account Closed
2
+
3
+ %p
4
+ The sign-in account once associated with this card has been removed, the card
5
+ has been anonymized, and its data fields have been deleted.
data/set/all/account.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # for extending the Card class
1
2
  module ClassMethods
2
3
  def default_accounted_type_id
3
4
  UserID
@@ -0,0 +1,39 @@
1
+
2
+ #account-closure.p-3
3
+ %h2
4
+ Close Account
5
+
6
+ .alert-danger.p-4.my-3
7
+ %strong Warning:
8
+ this action cannot be undone
9
+
10
+ %p
11
+ Closing your account entails:
12
+ %ul
13
+ %li Deleting your account information and personal data
14
+ %li Anonymizing your edits
15
+
16
+ It does
17
+ %em not
18
+ entail deleting your collaborative contributions; that would be messy and unfair to
19
+ collaborators.
20
+
21
+ .closure-deletions
22
+ The following cards will be permanently deleted:
23
+
24
+ %ul.py-2
25
+ - card.accounted.closure_deletions.each do |deletee|
26
+ %li
27
+ = link_to_card deletee
28
+
29
+ .button-form-group.py-3.justify-content-end
30
+ - accounted = card.accounted
31
+ - confirmation = t :account_confirm_delete_account, accounted: accounted.name
32
+ %a.btn.btn-primary.slotter{ href: path(success: { mark: "~#{accounted.id}",
33
+ redirect: true,
34
+ view: :closed_account }),
35
+ "data-method": :delete,
36
+ "data-remote": true,
37
+ "rel": "nofollow",
38
+ "data-confirm": confirmation }
39
+ = t :account_close_account
@@ -5,7 +5,7 @@ event :set_default_salt, :prepare_to_validate, on: :create do
5
5
  end
6
6
 
7
7
  event :set_default_status, :prepare_to_validate, on: :create do
8
- field :status, content: (accounted&.try(:default_account_status) || "active")
8
+ field :status, content: accounted&.try(:default_account_status) || "active"
9
9
  end
10
10
 
11
11
  # ON UPDATE
@@ -30,13 +30,30 @@ end
30
30
  # INTEGRATION
31
31
 
32
32
  %i[password_reset_email verification_email welcome_email].each do |email|
33
- event "send_#{email}".to_sym, :integrate, trigger: :required do
33
+ event :"send_#{email}", :integrate, trigger: :required do
34
34
  send_account_email email
35
35
  end
36
36
  end
37
37
 
38
+ # NOTE: this only works in the context of an action.
39
+ # if run independently, it will not activate an account
40
+ event :activate_account do
41
+ field :status, content: "active"
42
+ trigger_event! :send_welcome_email
43
+ end
44
+
45
+ event :delete_account, :prepare_to_validate, on: :delete do
46
+ subcard accounted.close_account
47
+ end
48
+
49
+ event :signout_upon_delete, :integrate, on: :delete, when: :current_account? do
50
+ Self::Signin.signout
51
+ end
52
+
38
53
  ## EVENT HELPERS
39
54
 
55
+ private
56
+
40
57
  def activatable
41
58
  abort :failure, "no field manipulation mid-activation" if subcards.present?
42
59
  # above is necessary because activation uses super user (Decko Bot),
@@ -44,13 +61,6 @@ def activatable
44
61
  yield
45
62
  end
46
63
 
47
- # NOTE: this only works in the context of an action.
48
- # if run independently, it will not activate an account
49
- event :activate_account do
50
- field :status, content: "active"
51
- trigger_event! :send_welcome_email
52
- end
53
-
54
64
  def verifying_token success, failure
55
65
  requiring_token do |token|
56
66
  result = Auth::Token.decode token
@@ -63,10 +73,10 @@ def verifying_token success, failure
63
73
  end
64
74
 
65
75
  def requiring_token
66
- if !(token = Env.params[:token])
67
- errors.add :token, "is required"
68
- else
76
+ if (token = Env.params[:token])
69
77
  yield token
78
+ else
79
+ errors.add :token, "is required"
70
80
  end
71
81
  end
72
82
 
@@ -1,13 +1,9 @@
1
1
  format do
2
- view :verify_url, cache: :never, denial: :blank do
3
- raise Error::PermissionDenied unless card.ok?(:create) || card.action
4
-
2
+ view :verify_url, cache: :never, denial: :blank, perms: :verify_url_ok? do
5
3
  token_url :verify_and_activate, anonymous: true
6
4
  end
7
5
 
8
- view :reset_password_url, denial: :blank do
9
- raise Error::PermissionDenied unless card.password_card.ok? :update
10
-
6
+ view :reset_password_url, denial: :blank, perms: :reset_password_ok? do
11
7
  token_url :reset_password
12
8
  end
13
9
 
@@ -23,6 +19,18 @@ format do
23
19
  view :verify_days, :token_days
24
20
  view :reset_password_days, :token_days
25
21
 
22
+ view :closure, perms: :delete, template: :haml, wrap: :slot
23
+
24
+ private
25
+
26
+ def verify_url_ok?
27
+ card.ok?(:create) || card.action
28
+ end
29
+
30
+ def reset_password_ok?
31
+ card.password_card.ok? :update
32
+ end
33
+
26
34
  def token_url trigger, extra_payload={}
27
35
  card_url path(action: :update,
28
36
  card: { trigger: trigger },
@@ -50,8 +58,8 @@ format :html do
50
58
  end
51
59
 
52
60
  before :content_formgroups do
53
- voo.edit_structure = [[:email, title: "email"],
54
- [:password, title: "password"]]
61
+ voo.edit_structure = [[:email, { title: "email" }],
62
+ [:password, { title: "password" }]]
55
63
  end
56
64
 
57
65
  view :token_expiry do
@@ -61,6 +69,6 @@ end
61
69
 
62
70
  format :email_html do
63
71
  def mail context, fields
64
- super context, fields.reverse_merge(to: card.email)
72
+ super(context, fields.reverse_merge(to: card.email))
65
73
  end
66
74
  end
data/set/right/account.rb CHANGED
@@ -7,10 +7,16 @@ card_accessor :status
7
7
 
8
8
  require_field :email
9
9
 
10
+ STATUS_OPTIONS = %w[unapproved unverified active blocked].freeze
11
+
10
12
  def own_account?
11
13
  accounted&.try :own_account?
12
14
  end
13
15
 
16
+ def current_account?
17
+ accounted&.try :current_account?
18
+ end
19
+
14
20
  def accounted
15
21
  left
16
22
  end
@@ -28,13 +34,6 @@ def ok_to_update?
28
34
  (own_account? && !name_changed? && !type_id_changed?) || super
29
35
  end
30
36
 
31
- def changes_visible? act
32
- act.actions_affecting(act.card).each do |action|
33
- return true if action.card.ok? :read
34
- end
35
- false
36
- end
37
-
38
37
  def send_account_email email_template
39
38
  ecard = Card[email_template]
40
39
  unless ecard&.type_id == EmailTemplateID
@@ -44,12 +43,8 @@ def send_account_email email_template
44
43
  ecard.deliver self, to: email
45
44
  end
46
45
 
47
- def method_missing method, *args
48
- return super unless args.empty? && (matches = method.match(/^(?<status>.*)\?$/))
49
-
50
- status == matches[:status]
51
- end
52
-
53
- def respond_to_missing? method, _include_private=false
54
- method.match?(/\?$/) ? true : super
46
+ STATUS_OPTIONS.each do |stat|
47
+ define_method "#{stat}?" do
48
+ status == stat
49
+ end
55
50
  end
@@ -5,7 +5,7 @@ assign_type :phrase
5
5
  PASSWORD_REGEX = {
6
6
  lower: /[a-z]/,
7
7
  upper: /[A-Z]/,
8
- special_char: /[!"#$%&'()*+,-.\/:;<=>?@\[\]\\^_`{|}~]/,
8
+ special_char: %r{[!"#$%&'()*+,-./:;<=>?@\[\]\\^_`{|}~]},
9
9
  number: /\d+/,
10
10
  letter: /[a-zA-Z]/
11
11
  }.freeze
data/set/right/status.rb CHANGED
@@ -10,7 +10,7 @@ format :html do
10
10
  end
11
11
 
12
12
  def option_names
13
- %w[unapproved unverified active blocked] # system
13
+ Right::Account::STATUS_OPTIONS
14
14
  end
15
15
 
16
16
  def ok_to_update?
data/set/self/role.rb CHANGED
@@ -8,6 +8,7 @@ class << self
8
8
  def role_ids user_id
9
9
  role_hash.each_with_object([]) do |(role_id, member_ids), all_role_ids|
10
10
  next unless member_ids.include? user_id
11
+
11
12
  all_role_ids << role_id
12
13
  end
13
14
  end
data/set/self/signin.rb CHANGED
@@ -17,8 +17,8 @@ event :signin_success, after: :signin do
17
17
  end
18
18
 
19
19
  event :signout, :validate, on: :delete do
20
- Env.reset_session
21
20
  Auth.signin AnonymousID
21
+ Env.reset_session
22
22
  abort :success
23
23
  end
24
24
 
@@ -168,7 +168,7 @@ format :html do
168
168
  end
169
169
 
170
170
  def signin_success
171
- { redirect: true, mark: (Env.interrupted_action || "*previous") }
171
+ { redirect: true, mark: Env.interrupted_action || "*previous" }
172
172
  end
173
173
 
174
174
  def signin_button
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: card-mod-account
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan McCutchen
8
8
  - Philipp Kühl
9
9
  - Gerry Gleason
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2024-11-22 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: card
@@ -18,84 +17,84 @@ dependencies:
18
17
  requirements:
19
18
  - - '='
20
19
  - !ruby/object:Gem::Version
21
- version: 1.108.1
20
+ version: 1.109.0
22
21
  type: :runtime
23
22
  prerelease: false
24
23
  version_requirements: !ruby/object:Gem::Requirement
25
24
  requirements:
26
25
  - - '='
27
26
  - !ruby/object:Gem::Version
28
- version: 1.108.1
27
+ version: 1.109.0
29
28
  - !ruby/object:Gem::Dependency
30
29
  name: card-mod-email
31
30
  requirement: !ruby/object:Gem::Requirement
32
31
  requirements:
33
32
  - - '='
34
33
  - !ruby/object:Gem::Version
35
- version: 0.18.1
34
+ version: 0.19.0
36
35
  type: :runtime
37
36
  prerelease: false
38
37
  version_requirements: !ruby/object:Gem::Requirement
39
38
  requirements:
40
39
  - - '='
41
40
  - !ruby/object:Gem::Version
42
- version: 0.18.1
41
+ version: 0.19.0
43
42
  - !ruby/object:Gem::Dependency
44
43
  name: card-mod-permissions
45
44
  requirement: !ruby/object:Gem::Requirement
46
45
  requirements:
47
46
  - - '='
48
47
  - !ruby/object:Gem::Version
49
- version: 0.18.1
48
+ version: 0.19.0
50
49
  type: :runtime
51
50
  prerelease: false
52
51
  version_requirements: !ruby/object:Gem::Requirement
53
52
  requirements:
54
53
  - - '='
55
54
  - !ruby/object:Gem::Version
56
- version: 0.18.1
55
+ version: 0.19.0
57
56
  - !ruby/object:Gem::Dependency
58
57
  name: card-mod-list
59
58
  requirement: !ruby/object:Gem::Requirement
60
59
  requirements:
61
60
  - - '='
62
61
  - !ruby/object:Gem::Version
63
- version: 0.18.1
62
+ version: 0.19.0
64
63
  type: :runtime
65
64
  prerelease: false
66
65
  version_requirements: !ruby/object:Gem::Requirement
67
66
  requirements:
68
67
  - - '='
69
68
  - !ruby/object:Gem::Version
70
- version: 0.18.1
69
+ version: 0.19.0
71
70
  - !ruby/object:Gem::Dependency
72
71
  name: card-mod-integrate
73
72
  requirement: !ruby/object:Gem::Requirement
74
73
  requirements:
75
74
  - - '='
76
75
  - !ruby/object:Gem::Version
77
- version: 0.18.1
76
+ version: 0.19.0
78
77
  type: :runtime
79
78
  prerelease: false
80
79
  version_requirements: !ruby/object:Gem::Requirement
81
80
  requirements:
82
81
  - - '='
83
82
  - !ruby/object:Gem::Version
84
- version: 0.18.1
83
+ version: 0.19.0
85
84
  - !ruby/object:Gem::Dependency
86
85
  name: card-mod-edit
87
86
  requirement: !ruby/object:Gem::Requirement
88
87
  requirements:
89
88
  - - '='
90
89
  - !ruby/object:Gem::Version
91
- version: 0.18.1
90
+ version: 0.19.0
92
91
  type: :runtime
93
92
  prerelease: false
94
93
  version_requirements: !ruby/object:Gem::Requirement
95
94
  requirements:
96
95
  - - '='
97
96
  - !ruby/object:Gem::Version
98
- version: 0.18.1
97
+ version: 0.19.0
99
98
  description: ''
100
99
  email:
101
100
  - info@decko.org
@@ -110,17 +109,19 @@ files:
110
109
  - config/admin.yml
111
110
  - config/locales/de.yml
112
111
  - config/locales/en.yml
113
- - data/files/mod_account_script_asset_output/file.js
112
+ - data/files/mod_account/script/asset_output/file.js
114
113
  - data/real.yml
115
114
  - data/transform/20220815112551_move_roles.rb
116
115
  - data/transform/20240510141851_member_ids.rb
117
116
  - lib/card/mod/account.rb
118
117
  - set/abstract/account_field.rb
119
118
  - set/abstract/account_holder.rb
119
+ - set/abstract/closed_account.haml
120
120
  - set/all/account.rb
121
121
  - set/all/password_input.haml
122
122
  - set/all/password_input.rb
123
123
  - set/right/account.rb
124
+ - set/right/account/closure.haml
124
125
  - set/right/account/events.rb
125
126
  - set/right/account/views.rb
126
127
  - set/right/email.rb
@@ -153,7 +154,6 @@ metadata:
153
154
  documentation_url: http://docs.decko.org/
154
155
  card-mod: account
155
156
  card-mod-group: gem-defaults
156
- post_install_message:
157
157
  rdoc_options: []
158
158
  require_paths:
159
159
  - lib
@@ -161,15 +161,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
161
  requirements:
162
162
  - - ">="
163
163
  - !ruby/object:Gem::Version
164
- version: '3.0'
164
+ version: '3.2'
165
165
  required_rubygems_version: !ruby/object:Gem::Requirement
166
166
  requirements:
167
167
  - - ">="
168
168
  - !ruby/object:Gem::Version
169
169
  version: '0'
170
170
  requirements: []
171
- rubygems_version: 3.5.10
172
- signing_key:
171
+ rubygems_version: 3.6.8
173
172
  specification_version: 4
174
173
  summary: Email-based account handling for decko cards
175
174
  test_files: []