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.
- checksums.yaml +4 -4
- data/app/controllers/account/invitations_controller.rb +1 -144
- data/app/controllers/account/memberships_controller.rb +1 -130
- data/app/controllers/account/onboarding/user_details_controller.rb +1 -61
- data/app/controllers/account/onboarding/user_email_controller.rb +1 -63
- data/app/controllers/account/teams_controller.rb +1 -120
- data/app/controllers/account/users_controller.rb +1 -57
- data/app/controllers/concerns/account/invitations/controller_base.rb +150 -0
- data/app/controllers/concerns/account/memberships/controller_base.rb +136 -0
- data/app/controllers/concerns/account/onboarding/user_details/controller_base.rb +67 -0
- data/app/controllers/concerns/account/onboarding/user_email/controller_base.rb +69 -0
- data/app/controllers/concerns/account/teams/controller_base.rb +126 -0
- data/app/controllers/concerns/account/users/controller_base.rb +63 -0
- data/app/models/concerns/invitations/base.rb +46 -0
- data/app/models/concerns/memberships/base.rb +137 -0
- data/app/models/concerns/teams/base.rb +51 -0
- data/app/models/concerns/users/base.rb +164 -0
- data/app/models/invitation.rb +1 -52
- data/app/models/invitations.rb +5 -0
- data/app/models/membership.rb +1 -143
- data/app/models/memberships.rb +5 -0
- data/app/models/team.rb +1 -59
- data/app/models/teams.rb +5 -0
- data/app/models/user.rb +1 -170
- data/app/models/users.rb +5 -0
- data/config/routes.rb +40 -0
- data/lib/bullet_train/version.rb +1 -1
- metadata +16 -2
data/app/models/user.rb
CHANGED
@@ -1,41 +1,5 @@
|
|
1
1
|
class User < ApplicationRecord
|
2
|
-
|
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
|
data/app/models/users.rb
ADDED
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
|
data/lib/bullet_train/version.rb
CHANGED
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.
|
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-
|
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
|