card-mod-account 0.15.6 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,11 +2,19 @@ include_set Abstract::AccountField
2
2
 
3
3
  assign_type :phrase
4
4
 
5
+ PASSWORD_REGEX = {
6
+ lower: /[a-z]/,
7
+ upper: /[A-Z]/,
8
+ special_char: /[!"#$%&'()*+,-.\/:;<=>?@\[\]\\^_`{|}~]/,
9
+ number: /\d+/,
10
+ letter: /[a-zA-Z]/
11
+ }.freeze
12
+
5
13
  def history?
6
14
  false
7
15
  end
8
16
 
9
- def ok_to_read
17
+ def ok_to_read?
10
18
  own_account? || super
11
19
  end
12
20
 
@@ -15,14 +23,27 @@ event :encrypt_password, :store, on: :save, changed: :content do
15
23
  self.content = Auth.encrypt content, salt
16
24
 
17
25
  # errors.add :password, 'need a valid salt'
18
- # turns out we have a lot of existing account without a salt.
26
+ # turns out we have a lot of existing accounts without a salt.
19
27
  # not sure when that broke??
20
28
  end
21
29
 
22
- event :validate_password, :validate, on: :save do
23
- return if content.length > 3
30
+ event :validate_password_length, :validate, on: :save do
31
+ min_pw_length = Cardio.config.account_password_length
32
+ return if content.length >= min_pw_length
33
+
34
+ errors.add :password, t(:account_password_length, num_char: min_pw_length)
35
+ end
36
+
37
+ event :validate_password_chars, :validate, on: :save do
38
+ pw_requirements = check_password_regex(
39
+ Cardio.config.account_password_requirements,
40
+ PASSWORD_REGEX,
41
+ content
42
+ )
43
+ return unless pw_requirements
24
44
 
25
- errors.add :password, t(:account_password_length)
45
+ error_message = consolidated_password_error_message(pw_requirements)
46
+ errors.add :password, t(:account_password_requirements, char_type: error_message)
26
47
  end
27
48
 
28
49
  event :validate_password_present, :prepare_to_validate, on: :update do
@@ -33,14 +54,37 @@ view :raw do
33
54
  t :account_encrypted
34
55
  end
35
56
 
57
+ private
58
+
59
+ def check_password_regex char_types, regex_hash, password
60
+ pw_requirements = []
61
+
62
+ char_types.each do |char_type|
63
+ if regex_hash.key?(char_type) && password !~ regex_hash[char_type]
64
+ pw_requirements << :"account_password_requirement_#{char_type}"
65
+ end
66
+ end
67
+ pw_requirements unless pw_requirements.empty?
68
+ end
69
+
70
+ private
71
+
72
+ def consolidated_password_error_message err_messages
73
+ error_message = err_messages.map { |message| t(message) }
74
+ if error_message.length > 2
75
+ "#{error_message[0...-1].join(', ')}, and #{error_message[-1]}"
76
+ else
77
+ error_message.join(" and ")
78
+ end
79
+ end
80
+
36
81
  format :html do
37
82
  view :core, wrap: :em do
38
83
  render_raw
39
84
  end
40
85
 
41
- view :input do
42
- card.content = ""
43
- password_field :content, class: "d0-card-content", autocomplete: autocomplete?
86
+ def input_type
87
+ :password
44
88
  end
45
89
 
46
90
  def autocomplete?
data/set/right/status.rb CHANGED
@@ -13,7 +13,7 @@ def option_names
13
13
  %w[unapproved unverified active blocked] # system
14
14
  end
15
15
 
16
- def ok_to_update
16
+ def ok_to_update?
17
17
  if own_account? && !Auth.always_ok?
18
18
  deny_because you_cant(t(:account_deny_not_change_own_account))
19
19
  else
@@ -0,0 +1,13 @@
1
+ include_set Abstract::AccountHolder
2
+
3
+ def account
4
+ nil
5
+ end
6
+
7
+ def account?
8
+ false
9
+ end
10
+
11
+ def admin?
12
+ false
13
+ end
data/set/self/role.rb CHANGED
@@ -1,18 +1,14 @@
1
1
  class << self
2
2
  CACHE_KEY = "ROLEHASH".freeze
3
3
 
4
- def load_rolehash
5
- ::Card.cache.fetch(CACHE_KEY) do
6
- generate_rolehash
7
- end
4
+ def role_hash
5
+ @role_hash ||= load_rolehash
8
6
  end
9
7
 
10
- def generate_rolehash
11
- Auth.as_bot do
12
- Card.search(left: { type_id: Card::RoleID }, right_id: Card::MembersID)
13
- .each_with_object({}) do |member_card, hash|
14
- hash[member_card.left_id] = ::Set.new member_card.item_ids
15
- end
8
+ def role_ids user_id
9
+ role_hash.each_with_object([]) do |(role_id, member_ids), all_role_ids|
10
+ next unless member_ids.include? user_id
11
+ all_role_ids << role_id
16
12
  end
17
13
  end
18
14
 
@@ -25,14 +21,20 @@ class << self
25
21
  @role_hash = nil
26
22
  end
27
23
 
28
- def role_hash
29
- @role_hash ||= load_rolehash
24
+ private
25
+
26
+ def load_rolehash
27
+ ::Card.cache.fetch(CACHE_KEY) do
28
+ generate_rolehash
29
+ end
30
30
  end
31
31
 
32
- def role_ids user_id
33
- role_hash.each_with_object([]) do |(role_id, member_ids), all_role_ids|
34
- next unless member_ids.include? user_id
35
- all_role_ids << role_id
32
+ def generate_rolehash
33
+ Auth.as_bot do
34
+ Card.search(left: { type_id: Card::RoleID }, right_id: Card::MembersID)
35
+ .each_with_object({}) do |member_card, hash|
36
+ hash[member_card.left_id] = ::Set.new member_card.item_ids
37
+ end
36
38
  end
37
39
  end
38
40
  end
data/set/self/signin.rb CHANGED
@@ -34,7 +34,7 @@ def email_from_field
34
34
  @email_from_field ||= field_content(:email)
35
35
  end
36
36
 
37
- def ok_to_read
37
+ def ok_to_read?
38
38
  true
39
39
  end
40
40
 
@@ -0,0 +1,5 @@
1
+ include_set Abstract::AccountHolder
2
+
3
+ def admin?
4
+ true
5
+ end
data/set/type/role.rb CHANGED
@@ -9,6 +9,20 @@ format :html do
9
9
  role_checkbox
10
10
  end
11
11
 
12
+ view :configs do
13
+ configs_by_cat = card.all_admin_configs_grouped_by(:roles, :category)[card.codename]
14
+ configs_by_cat.map do |(cat, configs)|
15
+ if cat == "cardtypes"
16
+ nested_list_section cat.capitalize,
17
+ card.config_codenames_grouped_by_title(configs)
18
+ elsif cat == "views"
19
+ next
20
+ else
21
+ list_section cat.capitalize, configs.map { |c| c.codename.to_sym }, :closed_bar
22
+ end
23
+ end
24
+ end
25
+
12
26
  def role_checkbox
13
27
  name = card.disabled? ? "add_item" : "drop_item"
14
28
  subformat(Auth.current.field(:disabled_roles)).card_form :update do
@@ -45,7 +45,7 @@ format :html do
45
45
  end
46
46
 
47
47
  def account_lines
48
- if card.account
48
+ if card.account?
49
49
  verification_lines
50
50
  else
51
51
  [t(:account_missing_account)]
data/set/type/signup.rb CHANGED
@@ -1,4 +1,4 @@
1
- include_set Abstract::Accountable
1
+ include_set Abstract::AccountHolder
2
2
 
3
3
  basket[:non_createable_types] << :signup
4
4
 
@@ -37,6 +37,8 @@ event :act_as_current_for_integrate_stage, :integrate, on: :create do
37
37
  Auth.current_id = id
38
38
  end
39
39
 
40
+ private
41
+
40
42
  def request_verification
41
43
  acct = field :account
42
44
  acct.field :status, content: "unverified"
data/set/type/user.rb CHANGED
@@ -1,11 +1,13 @@
1
- include_set Abstract::Accountable
1
+ include_set Abstract::AccountHolder
2
+
3
+ basket[:roles_for_first_user] = %i[help_desk shark administrator]
2
4
 
3
5
  attr_accessor :email
4
6
 
5
7
  format :html do
6
8
  delegate :needs_setup?, to: Card::Auth
7
9
 
8
- view :setup, unknown: true, perms: :needs_setup? do
10
+ view :setup, unknown: true, perms: :needs_setup?, cache: :never do
9
11
  with_nest_mode :edit do
10
12
  voo.title = "Your deck is ready to go!" # LOCALIZE
11
13
  voo.show! :help
@@ -36,37 +38,37 @@ format :html do
36
38
 
37
39
  def setup_hidden_fields
38
40
  hidden_tags(
39
- setup: true,
40
- success: { redirect: true, mark: path(mark: "") },
41
- "card[type_id]" => Card.default_accounted_type_id
41
+ card: {
42
+ type_id: Card.default_accounted_type_id,
43
+ trigger: %w[check_setup]
44
+ },
45
+ success: { redirect: true, mark: path(mark: "") }
42
46
  )
43
47
  end
44
48
  end
45
49
 
46
- # FIXME. use trigger
47
- def setup?
48
- Card::Env.params[:setup]
49
- end
50
-
51
- event :setup_as_bot, before: :check_permissions, on: :create, when: :setup? do
50
+ event :check_setup, before: :check_permissions, on: :create, trigger: :required do
52
51
  abort :failure unless Auth.needs_setup?
53
52
  Auth.as_bot
53
+ @setup_approved = true
54
54
  # we need bot authority to set the initial administrator roles
55
55
  # this is granted and inspected here as a separate event for
56
56
  # flexibility and security when configuring initial setups
57
57
  end
58
58
 
59
- event :setup_first_user, :prepare_to_store, on: :create, when: :setup? do
59
+ event :setup_first_user, :finalize, on: :create, when: :setup? do
60
60
  subcard %i[signup_alert_email to].cardname, content: name
61
- roles_for_first_user.each do |role|
62
- subcard [role, :members], content: name
61
+ basket[:roles_for_first_user].map(&:cardname).each do |role|
62
+ subcard [role, :members].cardname, content: name
63
63
  end
64
64
  end
65
65
 
66
- def roles_for_first_user
67
- %i[help_desk shark administrator].map(&:cardname)
68
- end
69
-
70
66
  event :signin_after_setup, :integrate, on: :create, when: :setup? do
71
67
  Auth.signin id
72
68
  end
69
+
70
+ private
71
+
72
+ def setup?
73
+ @setup_approved == true
74
+ end
@@ -0,0 +1,5 @@
1
+ # needed because of the present of Set cards like Signup+account, which
2
+ # are not true account cards.
3
+ def own_account?
4
+ false
5
+ end
@@ -1,3 +1,5 @@
1
+ include_set Abstract::IdList
2
+
1
3
  assign_type :list
2
4
 
3
5
  event :update_role_cache, :finalize do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: card-mod-account
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.6
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ethan McCutchen
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-05-02 00:00:00.000000000 Z
13
+ date: 2024-06-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: card
@@ -18,84 +18,84 @@ dependencies:
18
18
  requirements:
19
19
  - - '='
20
20
  - !ruby/object:Gem::Version
21
- version: 1.105.6
21
+ version: 1.107.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - '='
27
27
  - !ruby/object:Gem::Version
28
- version: 1.105.6
28
+ version: 1.107.0
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: card-mod-email
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - '='
34
34
  - !ruby/object:Gem::Version
35
- version: 0.15.6
35
+ version: 0.17.0
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - '='
41
41
  - !ruby/object:Gem::Version
42
- version: 0.15.6
42
+ version: 0.17.0
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: card-mod-permissions
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - '='
48
48
  - !ruby/object:Gem::Version
49
- version: 0.15.6
49
+ version: 0.17.0
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - '='
55
55
  - !ruby/object:Gem::Version
56
- version: 0.15.6
56
+ version: 0.17.0
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: card-mod-list
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - '='
62
62
  - !ruby/object:Gem::Version
63
- version: 0.15.6
63
+ version: 0.17.0
64
64
  type: :runtime
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
68
  - - '='
69
69
  - !ruby/object:Gem::Version
70
- version: 0.15.6
70
+ version: 0.17.0
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: card-mod-integrate
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - '='
76
76
  - !ruby/object:Gem::Version
77
- version: 0.15.6
77
+ version: 0.17.0
78
78
  type: :runtime
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
82
  - - '='
83
83
  - !ruby/object:Gem::Version
84
- version: 0.15.6
84
+ version: 0.17.0
85
85
  - !ruby/object:Gem::Dependency
86
86
  name: card-mod-edit
87
87
  requirement: !ruby/object:Gem::Requirement
88
88
  requirements:
89
89
  - - '='
90
90
  - !ruby/object:Gem::Version
91
- version: 0.15.6
91
+ version: 0.17.0
92
92
  type: :runtime
93
93
  prerelease: false
94
94
  version_requirements: !ruby/object:Gem::Requirement
95
95
  requirements:
96
96
  - - '='
97
97
  - !ruby/object:Gem::Version
98
- version: 0.15.6
98
+ version: 0.17.0
99
99
  description: ''
100
100
  email:
101
101
  - info@decko.org
@@ -103,15 +103,23 @@ executables: []
103
103
  extensions: []
104
104
  extra_rdoc_files: []
105
105
  files:
106
+ - LICENSE
106
107
  - README.md
108
+ - assets/script/toggle_visibility.js.coffee
107
109
  - assets/style/account.scss
110
+ - config/admin.yml
108
111
  - config/locales/de.yml
109
112
  - config/locales/en.yml
113
+ - data/files/mod_account_script_asset_output/file.js
110
114
  - data/real.yml
111
- - db/migrate_core_cards/20220815112551_move_roles.rb
115
+ - data/transform/20220815112551_move_roles.rb
116
+ - data/transform/20240510141851_member_ids.rb
117
+ - lib/card/mod/account.rb
112
118
  - set/abstract/account_field.rb
113
- - set/abstract/accountable.rb
119
+ - set/abstract/account_holder.rb
114
120
  - set/all/account.rb
121
+ - set/all/password_input.haml
122
+ - set/all/password_input.rb
115
123
  - set/right/account.rb
116
124
  - set/right/account/events.rb
117
125
  - set/right/account/views.rb
@@ -120,15 +128,18 @@ files:
120
128
  - set/right/roles.rb
121
129
  - set/right/salt.rb
122
130
  - set/right/status.rb
131
+ - set/self/anonymous.rb
123
132
  - set/self/role.rb
124
133
  - set/self/signin.rb
125
134
  - set/self/signin/core.haml
135
+ - set/self/wagn_bot.rb
126
136
  - set/type/role.rb
127
137
  - set/type/signup.rb
128
138
  - set/type/signup/core.haml
129
139
  - set/type/signup/views.rb
130
140
  - set/type/user.rb
131
141
  - set/type/user/setup_help.haml
142
+ - set/type_plus_right/cardtype/account.rb
132
143
  - set/type_plus_right/role/members.rb
133
144
  - set/type_plus_right/user/email.rb
134
145
  homepage: https://decko.org
@@ -150,14 +161,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
161
  requirements:
151
162
  - - ">="
152
163
  - !ruby/object:Gem::Version
153
- version: '2.5'
164
+ version: '3.0'
154
165
  required_rubygems_version: !ruby/object:Gem::Requirement
155
166
  requirements:
156
167
  - - ">="
157
168
  - !ruby/object:Gem::Version
158
169
  version: '0'
159
170
  requirements: []
160
- rubygems_version: 3.2.33
171
+ rubygems_version: 3.5.10
161
172
  signing_key:
162
173
  specification_version: 4
163
174
  summary: Email-based account handling for decko cards
@@ -1,54 +0,0 @@
1
- def account
2
- fetch :account, new: {}
3
- end
4
-
5
- def default_account_status
6
- "active"
7
- end
8
-
9
- def current_account?
10
- id && Auth.current_id == id
11
- end
12
-
13
- format :html do
14
- def default_board_tab
15
- card.current_account? ? :account_tab : super
16
- end
17
-
18
- view :account_tab do
19
- board_pill_sections "Account" do
20
- [["Settings", account_details_items],
21
- ["Content", account_content_items]]
22
- end
23
- end
24
-
25
- def show_account_tab?
26
- card.account.real?
27
- end
28
-
29
- def account_formgroups
30
- Auth.as_bot do
31
- subformat(card.account)._render :content_formgroups, structure: true
32
- end
33
- end
34
-
35
- def account_details_items
36
- [
37
- ["Email and Password", :account,
38
- { path: { slot: { hide: %i[help_link board_link] } } }],
39
- ["Roles", :roles,
40
- { path: { view: :content } }],
41
- ["Notifications", :follow],
42
- # FIXME: this should be added in api_key mod!
43
- ["API", :account,
44
- { path: { view: :api_key,
45
- items: { view: :content },
46
- slot: { hide: %i[help_link board_link] } } }]
47
- ]
48
- end
49
-
50
- def account_content_items
51
- [["Created", :created],
52
- ["Edited", :edited]]
53
- end
54
- end