bullet_train 1.0.1 → 1.0.5

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.
data/app/models/user.rb CHANGED
@@ -1,41 +1,5 @@
1
1
  class User < ApplicationRecord
2
- # 🚫 DEFAULT BULLET TRAIN USER FUNCTIONALITY
3
- # Typically you should avoid adding your own functionality in this section to avoid merge conflicts in the future.
4
- # (If you specifically want to change Bullet Train's default behavior, that's OK and you can do that here.)
5
-
6
- if two_factor_authentication_enabled?
7
- devise :two_factor_authenticatable, :two_factor_backupable, :omniauthable,
8
- :registerable, :recoverable, :rememberable, :trackable, :validatable,
9
- otp_secret_encryption_key: ENV["TWO_FACTOR_ENCRYPTION_KEY"]
10
- else
11
- devise :omniauthable, :database_authenticatable, :registerable,
12
- :recoverable, :rememberable, :trackable, :validatable
13
- end
14
-
15
- # teams
16
- has_many :memberships, dependent: :destroy
17
- has_many :scaffolding_absolutely_abstract_creative_concepts_collaborators, through: :memberships
18
- has_many :teams, through: :memberships
19
- belongs_to :current_team, class_name: "Team", optional: true
20
- accepts_nested_attributes_for :current_team
21
-
22
- # oauth providers
23
- has_many :oauth_stripe_accounts, class_name: "Oauth::StripeAccount" if stripe_enabled?
24
-
25
- # platform functionality.
26
- belongs_to :platform_agent_of, class_name: "Platform::Application", optional: true
27
-
28
- # validations
29
- validate :real_emails_only
30
- validates :time_zone, inclusion: {in: ActiveSupport::TimeZone.all.map(&:name)}, allow_nil: true
31
-
32
- # callbacks
33
- after_update :set_teams_time_zone
34
-
35
- # ✅ YOUR APPLICATION'S USER FUNCTIONALITY
36
- # This is the place where you should implement your own features on top of Bullet Train's user functionality. There
37
- # are a bunch of Super Scaffolding hooks here by default to try and help keep generated code logically organized.
38
-
2
+ include Users::Core
39
3
  # 🚅 add concerns above.
40
4
 
41
5
  # 🚅 add belongs_to associations above.
@@ -55,137 +19,4 @@ class User < ApplicationRecord
55
19
  # 🚅 add delegations above.
56
20
 
57
21
  # 🚅 add methods above.
58
-
59
- # 🚫 DEFAULT BULLET TRAIN USER FUNCTIONALITY
60
- # We put these at the bottom of this file to keep them out of the way. You should define your own methods above here.
61
-
62
- # TODO we need to update this to some sort of invalid email address or something
63
- # people know to ignore. it would be a security problem to have this pointing
64
- # at anybody's real email address.
65
- def email_is_oauth_placeholder?
66
- !!email.match(/noreply\+.*@bullettrain.co/)
67
- end
68
-
69
- def label_string
70
- name
71
- end
72
-
73
- def name
74
- full_name.present? ? full_name : email
75
- end
76
-
77
- def full_name
78
- [first_name_was, last_name_was].select(&:present?).join(" ")
79
- end
80
-
81
- def details_provided?
82
- first_name.present? && last_name.present? && current_team.name.present?
83
- end
84
-
85
- def send_welcome_email
86
- UserMailer.welcome(self).deliver_later
87
- end
88
-
89
- def create_default_team
90
- # This creates a `Membership`, because `User` `has_many :teams, through: :memberships`
91
- # TODO The team name should take into account the user's current locale.
92
- default_team = teams.create(name: "Your Team", time_zone: time_zone)
93
- memberships.find_by(team: default_team).update role_ids: [Role.admin.id]
94
- update(current_team: default_team)
95
- end
96
-
97
- def real_emails_only
98
- if ENV["REALEMAIL_API_KEY"] && !Rails.env.test?
99
- uri = URI("https://realemail.expeditedaddons.com")
100
-
101
- # Change the input parameters here
102
- uri.query = URI.encode_www_form({
103
- api_key: ENV["REAL_EMAIL_KEY"],
104
- email: email,
105
- fix_typos: false
106
- })
107
-
108
- # Results are returned as a JSON object
109
- result = JSON.parse(Net::HTTP.get_response(uri).body)
110
-
111
- if result["syntax_error"]
112
- errors.add(:email, "is not a valid email address")
113
- elsif result["domain_error"] || (result.key?("mx_records_found") && !result["mx_records_found"])
114
- errors.add(:email, "can't actually receive emails")
115
- elsif result["is_disposable"]
116
- errors.add(:email, "is a disposable email address")
117
- end
118
- end
119
- end
120
-
121
- def multiple_teams?
122
- teams.count > 1
123
- end
124
-
125
- def one_team?
126
- !multiple_teams?
127
- end
128
-
129
- def formatted_email_address
130
- if details_provided?
131
- "\"#{first_name} #{last_name}\" <#{email}>"
132
- else
133
- email
134
- end
135
- end
136
-
137
- def administrating_team_ids
138
- parent_ids_for(Role.admin, :memberships, :team)
139
- end
140
-
141
- def parent_ids_for(role, through, parent)
142
- parent_id_column = "#{parent}_id"
143
- key = "#{role.key}_#{through}_#{parent_id_column}s"
144
- return ability_cache[key] if ability_cache && ability_cache[key]
145
- role = nil if role.default?
146
- value = send(through).with_role(role).distinct.pluck(parent_id_column)
147
- current_cache = ability_cache || {}
148
- current_cache[key] = value
149
- update_column :ability_cache, current_cache
150
- value
151
- end
152
-
153
- def invalidate_ability_cache
154
- update_column(:ability_cache, {})
155
- end
156
-
157
- def otp_qr_code
158
- issuer = I18n.t("application.name")
159
- label = "#{issuer}:#{email}"
160
- RQRCode::QRCode.new(otp_provisioning_uri(label, issuer: issuer))
161
- end
162
-
163
- def scaffolding_absolutely_abstract_creative_concepts_collaborators
164
- Scaffolding::AbsolutelyAbstract::CreativeConcepts::Collaborator.joins(:membership).where(membership: {user_id: id})
165
- end
166
-
167
- def admin_scaffolding_absolutely_abstract_creative_concepts_ids
168
- scaffolding_absolutely_abstract_creative_concepts_collaborators.admins.pluck(:creative_concept_id)
169
- end
170
-
171
- def editor_scaffolding_absolutely_abstract_creative_concepts_ids
172
- scaffolding_absolutely_abstract_creative_concepts_collaborators.editors.pluck(:creative_concept_id)
173
- end
174
-
175
- def viewer_scaffolding_absolutely_abstract_creative_concepts_ids
176
- scaffolding_absolutely_abstract_creative_concepts_collaborators.viewers.pluck(:creative_concept_id)
177
- end
178
-
179
- def developer?
180
- return false unless ENV["DEVELOPER_EMAILS"]
181
- # we use email_was so they can't try setting their email to the email of an admin.
182
- return false unless email_was
183
- ENV["DEVELOPER_EMAILS"].split(",").include?(email_was)
184
- end
185
-
186
- def set_teams_time_zone
187
- teams.where(time_zone: nil).each do |team|
188
- team.update(time_zone: time_zone) if team.users.count == 1
189
- end
190
- end
191
22
  end
@@ -0,0 +1,5 @@
1
+ module Users
2
+ def self.table_name_prefix
3
+ "users_"
4
+ end
5
+ end
data/config/routes.rb CHANGED
@@ -1,2 +1,42 @@
1
1
  Rails.application.routes.draw do
2
+ namespace :account do
3
+ shallow do
4
+ resource :two_factor, only: [:create, :destroy]
5
+
6
+ # user-level onboarding tasks.
7
+ namespace :onboarding do
8
+ resources :user_details
9
+ resources :user_email
10
+ end
11
+
12
+ # user specific resources.
13
+ resources :users
14
+
15
+ # team-level resources.
16
+ resources :teams do
17
+ resources :invitations do
18
+ member do
19
+ get :accept
20
+ post :accept
21
+ end
22
+ end
23
+
24
+ resources :memberships do
25
+ member do
26
+ post :demote
27
+ post :promote
28
+ post :reinvite
29
+ end
30
+
31
+ collection do
32
+ get :search
33
+ end
34
+ end
35
+
36
+ member do
37
+ post :switch_to
38
+ end
39
+ end
40
+ end
41
+ end
2
42
  end
@@ -1,3 +1,3 @@
1
1
  module BulletTrain
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-23 00:00:00.000000000 Z
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -41,16 +41,30 @@ files:
41
41
  - app/controllers/account/onboarding/user_email_controller.rb
42
42
  - app/controllers/account/teams_controller.rb
43
43
  - app/controllers/account/users_controller.rb
44
+ - app/controllers/concerns/account/invitations/controller_base.rb
45
+ - app/controllers/concerns/account/memberships/controller_base.rb
46
+ - app/controllers/concerns/account/onboarding/user_details/controller_base.rb
47
+ - app/controllers/concerns/account/onboarding/user_email/controller_base.rb
48
+ - app/controllers/concerns/account/teams/controller_base.rb
49
+ - app/controllers/concerns/account/users/controller_base.rb
44
50
  - app/helpers/account/invitations_helper.rb
45
51
  - app/helpers/account/memberships_helper.rb
46
52
  - app/helpers/account/teams_helper.rb
47
53
  - app/helpers/account/users_helper.rb
48
54
  - app/helpers/invitation_only_helper.rb
49
55
  - app/helpers/invitations_helper.rb
56
+ - app/models/concerns/invitations/base.rb
57
+ - app/models/concerns/memberships/base.rb
58
+ - app/models/concerns/teams/base.rb
59
+ - app/models/concerns/users/base.rb
50
60
  - app/models/invitation.rb
61
+ - app/models/invitations.rb
51
62
  - app/models/membership.rb
63
+ - app/models/memberships.rb
52
64
  - app/models/team.rb
65
+ - app/models/teams.rb
53
66
  - app/models/user.rb
67
+ - app/models/users.rb
54
68
  - app/views/account/invitations/_breadcrumbs.html.erb
55
69
  - app/views/account/invitations/_form.html.erb
56
70
  - app/views/account/invitations/_invitation.json.jbuilder