bullet_train 1.0.3 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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/controllers/concerns/registrations/controller_base.rb +39 -0
- data/app/controllers/concerns/sessions/controller_base.rb +15 -0
- data/app/controllers/registrations_controller.rb +9 -0
- data/app/controllers/sessions_controller.rb +3 -0
- data/app/helpers/account/buttons_helper.rb +12 -0
- data/app/helpers/account/dates_helper.rb +38 -0
- data/app/helpers/account/forms_helper.rb +67 -0
- data/app/helpers/account/locale_helper.rb +51 -0
- data/app/helpers/account/markdown_helper.rb +5 -0
- data/app/helpers/account/role_helper.rb +5 -0
- data/app/helpers/attributes_helper.rb +32 -0
- data/app/helpers/email_helper.rb +7 -0
- data/app/helpers/images_helper.rb +7 -0
- data/app/mailers/concerns/mailers/base.rb +16 -0
- data/app/mailers/devise_mailer.rb +10 -0
- data/app/mailers/user_mailer.rb +24 -0
- data/app/models/concerns/invitations/{core.rb → base.rb} +1 -1
- data/app/models/concerns/memberships/{core.rb → base.rb} +1 -1
- data/app/models/concerns/teams/{core.rb → base.rb} +1 -1
- data/app/models/concerns/users/{core.rb → base.rb} +1 -1
- data/app/views/devise/confirmations/new.html.erb +16 -0
- data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/devise/mailer/password_change.html.erb +3 -0
- data/app/views/devise/mailer/reset_password_instructions.html.erb +30 -0
- data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/devise/passwords/edit.html.erb +17 -0
- data/app/views/devise/passwords/new.html.erb +20 -0
- data/app/views/devise/registrations/_two_factor.html.erb +42 -0
- data/app/views/devise/registrations/edit.html.erb +43 -0
- data/app/views/devise/registrations/new.html.erb +30 -0
- data/app/views/devise/sessions/new.html.erb +59 -0
- data/app/views/devise/sessions/pre_otp.js.erb +11 -0
- data/app/views/devise/shared/_links.html.erb +21 -0
- data/app/views/devise/shared/_oauth.html.erb +9 -0
- data/app/views/devise/unlocks/new.html.erb +16 -0
- data/config/locales/en/devise.en.yml +110 -0
- data/config/routes.rb +40 -0
- data/lib/bullet_train/version.rb +1 -1
- metadata +44 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91587205ff146fede77d497b179accabc819d44eca37b45a073b5e97bf0fdfd0
|
4
|
+
data.tar.gz: ea97e2ea8db1e6a2ce999bc06032777bc35b6d7ba6ef8f1740a408601f4a2bc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 119ac0424011467fd3aeab95aba0213aae4711ea1246288cd38b597149a685e2874e1891371ab680a0a0f3f8e50834a2faa501670379c633c40a62a05ad5bab5
|
7
|
+
data.tar.gz: 2c958dd9a290d69143dd2829018054fb5a28b35d85d3635f311cc1814087fee3ebc83d9c2f7e9dd238a3b527e24b7e251db8d0efc626ac22b082fa980775f6ca
|
@@ -1,146 +1,3 @@
|
|
1
1
|
class Account::InvitationsController < Account::ApplicationController
|
2
|
-
|
3
|
-
# link is authorization enough to claim membership on a team. see `#accept`
|
4
|
-
# for more information.
|
5
|
-
account_load_and_authorize_resource :invitation, :team, except: [:show]
|
6
|
-
|
7
|
-
# we skip the onboarding requirement for users claiming and invitation.
|
8
|
-
# this way the invitation gets accepted after they complete the devise
|
9
|
-
# workflow, but before they're prompted to complete their onboarding.
|
10
|
-
skip_before_action :ensure_onboarding_is_complete_and_set_next_step, only: :accept
|
11
|
-
skip_before_action :authenticate_user!, only: :accept
|
12
|
-
|
13
|
-
# GET /invitations
|
14
|
-
# GET /invitations.json
|
15
|
-
def index
|
16
|
-
redirect_to [:account, @team, :memberships]
|
17
|
-
end
|
18
|
-
|
19
|
-
# GET /invitations/1
|
20
|
-
# GET /invitations/1.json
|
21
|
-
def show
|
22
|
-
# it's important that we only allow invitations to be shown via their uuid,
|
23
|
-
# otherwise team members can just step the id in the url to claim an
|
24
|
-
# invitation that would escalate their privileges.
|
25
|
-
@invitation = Invitation.find_by(uuid: params[:id])
|
26
|
-
unless @invitation
|
27
|
-
raise I18n.t("global.notifications.not_found")
|
28
|
-
end
|
29
|
-
@team = @invitation.team
|
30
|
-
|
31
|
-
# backfill these objects for the locale magic, since we didn't use `account_load_and_authorize_resource`.
|
32
|
-
@child_object = @invitation
|
33
|
-
@parent_object = @team
|
34
|
-
|
35
|
-
render layout: "devise"
|
36
|
-
end
|
37
|
-
|
38
|
-
# POST /invitations/1/accept
|
39
|
-
# POST /invitations/1/accept.json
|
40
|
-
def accept
|
41
|
-
# unless the user is signed in.
|
42
|
-
if !current_user.present?
|
43
|
-
|
44
|
-
# keep track of the uuid of the invitation so we can reload it
|
45
|
-
# after they sign up. at this point we don't even know if it's
|
46
|
-
# valid, but that's fine.
|
47
|
-
session[:invitation_uuid] = params[:id]
|
48
|
-
|
49
|
-
# also, we'll queue devise up to return to the invitation url after a sign in.
|
50
|
-
session["user_return_to"] = request.path
|
51
|
-
|
52
|
-
# assume the user needs to create an account.
|
53
|
-
# this is not the default for devise, but a sensible default here.
|
54
|
-
redirect_to new_user_registration_path
|
55
|
-
|
56
|
-
else
|
57
|
-
|
58
|
-
@invitation = Invitation.find_by(uuid: params[:id])
|
59
|
-
|
60
|
-
if @invitation
|
61
|
-
@team = @invitation.team
|
62
|
-
if @invitation.is_for?(current_user) || request.post?
|
63
|
-
@invitation.accept_for(current_user)
|
64
|
-
redirect_to account_dashboard_path, notice: I18n.t("invitations.notifications.welcome", team_name: @team.name)
|
65
|
-
else
|
66
|
-
redirect_to account_invitation_path(@invitation.uuid)
|
67
|
-
end
|
68
|
-
else
|
69
|
-
redirect_to account_dashboard_path
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# GET /invitations/new
|
76
|
-
def new
|
77
|
-
@invitation.build_membership
|
78
|
-
@cancel_path = only_allow_path(params[:cancel_path])
|
79
|
-
end
|
80
|
-
|
81
|
-
# POST /invitations
|
82
|
-
# POST /invitations.json
|
83
|
-
def create
|
84
|
-
@invitation.membership.team = current_team
|
85
|
-
# this allows notifications to be sent to a user before they've accepted their invitation.
|
86
|
-
@invitation.membership.user_email = @invitation.email
|
87
|
-
@invitation.from_membership = current_membership
|
88
|
-
respond_to do |format|
|
89
|
-
if @invitation.save
|
90
|
-
format.html { redirect_to account_team_invitations_path(@team), notice: I18n.t("invitations.notifications.created") }
|
91
|
-
format.json { render :show, status: :created, location: [:account, @team, @invitation] }
|
92
|
-
else
|
93
|
-
format.html { render :new, status: :unprocessable_entity }
|
94
|
-
format.json { render json: @invitation.errors, status: :unprocessable_entity }
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
# DELETE /invitations/1
|
100
|
-
# DELETE /invitations/1.json
|
101
|
-
def destroy
|
102
|
-
@invitation.destroy
|
103
|
-
respond_to do |format|
|
104
|
-
format.html { redirect_to account_team_invitations_path(@team), notice: I18n.t("invitations.notifications.destroyed") }
|
105
|
-
format.json { head :no_content }
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
private
|
110
|
-
|
111
|
-
def manageable_role_keys
|
112
|
-
helpers.current_membership.manageable_roles.map(&:key)
|
113
|
-
end
|
114
|
-
|
115
|
-
# NOTE this method is only designed to work in the context of creating a invitation.
|
116
|
-
# we don't provide any support for updating invitations.
|
117
|
-
def invitation_params
|
118
|
-
# we use strong params first.
|
119
|
-
strong_params = params.require(:invitation).permit(
|
120
|
-
:email,
|
121
|
-
# 🚅 super scaffolding will insert new fields above this line.
|
122
|
-
# 🚅 super scaffolding will insert new arrays above this line.
|
123
|
-
membership_attributes: [
|
124
|
-
:user_first_name,
|
125
|
-
:user_last_name,
|
126
|
-
role_ids: []
|
127
|
-
],
|
128
|
-
)
|
129
|
-
|
130
|
-
# after that, we have to be more careful how we assign the roles.
|
131
|
-
# we can't let users assign roles to an invitation that they don't have permission
|
132
|
-
# to assign, but they do have permission to assign some to other team members.
|
133
|
-
if params[:invitation] && params[:invitation][:role_ids].present?
|
134
|
-
|
135
|
-
# ensure the list of role keys from the form only includes keys that they're allowed to assign.
|
136
|
-
assignable_role_keys_from_the_form = params[:invitation][:role_ids].map(&:to_i) & manageable_role_keys
|
137
|
-
|
138
|
-
strong_params[:role_ids] = assignable_role_keys_from_the_form
|
139
|
-
|
140
|
-
end
|
141
|
-
|
142
|
-
# 🚅 super scaffolding will insert processing for new fields above this line.
|
143
|
-
|
144
|
-
strong_params
|
145
|
-
end
|
2
|
+
include Invitations::ControllerBase
|
146
3
|
end
|
@@ -1,132 +1,3 @@
|
|
1
1
|
class Account::MembershipsController < Account::ApplicationController
|
2
|
-
|
3
|
-
|
4
|
-
def index
|
5
|
-
unless @memberships.count > 0
|
6
|
-
redirect_to account_team_invitations_path(@team), notice: I18n.t("memberships.notifications.no_members")
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def search
|
11
|
-
# TODO This is a particularly crazy example where we're doing the search logic ourselves in SQL.
|
12
|
-
# In the future, I could see us replacing this with a recommended example using Elasticsearch and the `searchkick` Ruby Gem.
|
13
|
-
limit = params[:limit] || 100
|
14
|
-
page = [params[:page].to_i, 1].max # Ensure we never have a negative or zero page value
|
15
|
-
search_term = "%#{params[:search]&.upcase}%"
|
16
|
-
offset = (page - 1) * limit
|
17
|
-
# Currently we're only searching on user.first_name, user.last_name, memberships.user_first_name and memberships.user_last_name. Should we also search on the email address?
|
18
|
-
# This query could use impromement. Currently if you search for "Ad Pal" you wouldn't find a user "Adam Pallozzi"
|
19
|
-
query = "UPPER(first_name) LIKE :search_term OR UPPER(last_name) LIKE :search_term OR UPPER(user_first_name) LIKE :search_term OR UPPER(user_last_name) LIKE :search_term"
|
20
|
-
# We're using left outer join here because we may get memberships that don't belong to a membership yet
|
21
|
-
memberships = @team.memberships.accessible_by(current_ability, :show).left_outer_joins(:user).where(query, search_term: search_term)
|
22
|
-
total_results = memberships.size
|
23
|
-
# the Areal.sql(LOWER(COALESCE...)) part means that if the user record doesn't exist or if there are records that start with a lower case letter, we will still sort everything correctly using the user.first_name instead.
|
24
|
-
memberships_array = memberships.limit(limit).offset(offset).order(Arel.sql("LOWER(COALESCE(first_name, user_first_name) )")).map { |membership| {id: membership.id, text: membership.label_string.to_s} }
|
25
|
-
results = {results: memberships_array, pagination: {more: (total_results > page * limit)}}
|
26
|
-
render json: results.to_json
|
27
|
-
end
|
28
|
-
|
29
|
-
def show
|
30
|
-
end
|
31
|
-
|
32
|
-
def edit
|
33
|
-
end
|
34
|
-
|
35
|
-
# PATCH/PUT /account/memberships/:id
|
36
|
-
# PATCH/PUT /account/memberships/:id.json
|
37
|
-
def update
|
38
|
-
respond_to do |format|
|
39
|
-
if @membership.update(membership_params)
|
40
|
-
format.html { redirect_to [:account, @membership], notice: I18n.t("memberships.notifications.updated") }
|
41
|
-
format.json { render :show, status: :ok, location: [:account, @membership] }
|
42
|
-
else
|
43
|
-
format.html { render :edit, status: :unprocessable_entity }
|
44
|
-
format.json { render json: @membership.errors, status: :unprocessable_entity }
|
45
|
-
end
|
46
|
-
rescue RemovingLastTeamAdminException => _
|
47
|
-
format.html { redirect_to [:account, @team, :memberships], alert: I18n.t("memberships.notifications.cant_demote") }
|
48
|
-
format.json { render json: {exception: I18n.t("memberships.notifications.cant_demote")}, status: :unprocessable_entity }
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def demote
|
53
|
-
@membership.roles.delete Role.admin
|
54
|
-
redirect_to account_team_memberships_path(@team)
|
55
|
-
rescue RemovingLastTeamAdminException => _
|
56
|
-
redirect_to account_team_memberships_path(@team), alert: I18n.t("memberships.notifications.cant_demote")
|
57
|
-
end
|
58
|
-
|
59
|
-
def promote
|
60
|
-
@membership.roles << Role.admin unless @membership.roles.include?(Role.admin)
|
61
|
-
redirect_to account_team_memberships_path(@team)
|
62
|
-
end
|
63
|
-
|
64
|
-
def destroy
|
65
|
-
# Instead of destroying the membership, we nullify the user_id and use the membership record as a 'Tombstone' for referencing past associations (eg message at-mentions and Scaffolding::CompletelyConcrete::TangibleThings::Assignment)
|
66
|
-
|
67
|
-
user_was = @membership.user
|
68
|
-
@membership.nullify_user
|
69
|
-
|
70
|
-
if user_was == current_user
|
71
|
-
# if a user removes themselves from a team, we'll have to send them to their dashboard.
|
72
|
-
redirect_to account_dashboard_path, notice: I18n.t("memberships.notifications.you_removed_yourself", team_name: @team.name)
|
73
|
-
else
|
74
|
-
redirect_to [:account, @team, :memberships], notice: I18n.t("memberships.notifications.destroyed")
|
75
|
-
end
|
76
|
-
rescue RemovingLastTeamAdminException
|
77
|
-
redirect_to account_team_memberships_path(@team), alert: I18n.t("memberships.notifications.cant_remove")
|
78
|
-
end
|
79
|
-
|
80
|
-
def reinvite
|
81
|
-
@invitation = Invitation.new(membership: @membership, team: @team, email: @membership.user_email, from_membership: current_membership)
|
82
|
-
if @invitation.save
|
83
|
-
redirect_to [:account, @team, :memberships], notice: I18n.t("account.memberships.notifications.reinvited")
|
84
|
-
else
|
85
|
-
redirect_to [:account, @team, :memberships], notice: "There was an error creating the invitation (#{@invitation.errors.full_messages.to_sentence})"
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def manageable_role_keys
|
92
|
-
helpers.current_membership.manageable_roles.map(&:key)
|
93
|
-
end
|
94
|
-
|
95
|
-
# NOTE this method is only designed to work in the context of updating a membership.
|
96
|
-
# we don't provide any support for creating memberships other than by an invitation.
|
97
|
-
def membership_params
|
98
|
-
# we use strong params first.
|
99
|
-
strong_params = params.require(:membership).permit(
|
100
|
-
:user_first_name,
|
101
|
-
:user_last_name,
|
102
|
-
:user_profile_photo_id,
|
103
|
-
# 🚅 super scaffolding will insert new fields above this line.
|
104
|
-
# 🚅 super scaffolding will insert new arrays above this line.
|
105
|
-
)
|
106
|
-
|
107
|
-
# after that, we have to be more careful how we update the roles.
|
108
|
-
# we can't let users remove roles from a membership that they don't have permission
|
109
|
-
# to remove, but we want to allow them to add or remove other roles they do have
|
110
|
-
# permission to assign to other team members.
|
111
|
-
if params[:membership] && params[:membership][:role_ids].present?
|
112
|
-
|
113
|
-
# first, start with the list of role keys already assigned to this membership.
|
114
|
-
existing_role_keys = @membership.role_ids
|
115
|
-
|
116
|
-
# generate a list of role keys we can't allow the current user to remove from this membership.
|
117
|
-
existing_role_keys_that_are_unmanageable = existing_role_keys - manageable_role_keys
|
118
|
-
|
119
|
-
# now let's ensure the list of role keys from the form only includes keys that they're allowed to assign.
|
120
|
-
assignable_role_keys_from_the_form = params[:membership][:role_ids].map(&:to_s) & manageable_role_keys
|
121
|
-
|
122
|
-
# any role keys that are manageable by the current user have to then come from the form data,
|
123
|
-
# otherwise we can assume they were removed by being unchecked.
|
124
|
-
strong_params[:role_ids] = existing_role_keys_that_are_unmanageable + assignable_role_keys_from_the_form
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
|
-
# 🚅 super scaffolding will insert processing for new fields above this line.
|
129
|
-
|
130
|
-
strong_params
|
131
|
-
end
|
2
|
+
include Account::Memberships::ControllerBase
|
132
3
|
end
|
@@ -1,63 +1,3 @@
|
|
1
1
|
class Account::Onboarding::UserDetailsController < Account::ApplicationController
|
2
|
-
|
3
|
-
load_and_authorize_resource class: "User"
|
4
|
-
|
5
|
-
# this is because cancancan doesn't let us set the instance variable name above.
|
6
|
-
before_action do
|
7
|
-
@user = @user_detail
|
8
|
-
end
|
9
|
-
|
10
|
-
# GET /users/1/edit
|
11
|
-
def edit
|
12
|
-
flash[:notice] = nil
|
13
|
-
end
|
14
|
-
|
15
|
-
# PATCH/PUT /users/1
|
16
|
-
# PATCH/PUT /users/1.json
|
17
|
-
def update
|
18
|
-
respond_to do |format|
|
19
|
-
if @user.update(user_params)
|
20
|
-
# if you update your own user account, devise will normally kick you out, so we do this instead.
|
21
|
-
bypass_sign_in current_user.reload
|
22
|
-
|
23
|
-
if @user.details_provided?
|
24
|
-
format.html { redirect_to account_team_path(@user.teams.first), notice: "" }
|
25
|
-
else
|
26
|
-
format.html {
|
27
|
-
flash[:error] = I18n.t("global.notifications.all_fields_required")
|
28
|
-
redirect_to edit_account_onboarding_user_detail_path(@user)
|
29
|
-
}
|
30
|
-
end
|
31
|
-
|
32
|
-
format.json { render :show, status: :ok, location: [:account, @user] }
|
33
|
-
else
|
34
|
-
format.html { render :edit, status: :unprocessable_entity }
|
35
|
-
format.json { render json: @user.errors, status: :unprocessable_entity }
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
# Never trust parameters from the scary internet, only allow the white list through.
|
43
|
-
def user_params
|
44
|
-
permitted_attributes = [
|
45
|
-
:first_name,
|
46
|
-
:last_name,
|
47
|
-
:time_zone,
|
48
|
-
# 🚅 super scaffolding will insert new fields above this line.
|
49
|
-
]
|
50
|
-
|
51
|
-
permitted_hash = {
|
52
|
-
# 🚅 super scaffolding will insert new arrays above this line.
|
53
|
-
}
|
54
|
-
|
55
|
-
if can? :edit, @user.current_team
|
56
|
-
permitted_hash[:current_team_attributes] = [:id, :name]
|
57
|
-
end
|
58
|
-
|
59
|
-
params.require(:user).permit(permitted_attributes, permitted_hash)
|
60
|
-
|
61
|
-
# 🚅 super scaffolding will insert processing for new fields above this line.
|
62
|
-
end
|
2
|
+
include Account::Onboarding::UserDetails::ControllerBase
|
63
3
|
end
|
@@ -1,65 +1,3 @@
|
|
1
1
|
class Account::Onboarding::UserEmailController < Account::ApplicationController
|
2
|
-
|
3
|
-
load_and_authorize_resource class: "User"
|
4
|
-
|
5
|
-
# this is because cancancan doesn't let us set the instance variable name above.
|
6
|
-
before_action do
|
7
|
-
@user = @user_email
|
8
|
-
end
|
9
|
-
|
10
|
-
# GET /users/1/edit
|
11
|
-
def edit
|
12
|
-
flash[:notice] = nil
|
13
|
-
if @user.email_is_oauth_placeholder?
|
14
|
-
@user.email = nil
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
# PATCH/PUT /users/1
|
19
|
-
# PATCH/PUT /users/1.json
|
20
|
-
def update
|
21
|
-
respond_to do |format|
|
22
|
-
if @user.update(user_params)
|
23
|
-
# if you update your own user account, devise will normally kick you out, so we do this instead.
|
24
|
-
bypass_sign_in current_user.reload
|
25
|
-
|
26
|
-
if !@user.email_is_oauth_placeholder?
|
27
|
-
@user.send_welcome_email
|
28
|
-
format.html { redirect_to account_team_path(@user.teams.first), notice: "" }
|
29
|
-
else
|
30
|
-
format.html {
|
31
|
-
flash[:error] = I18n.t("global.notifications.all_fields_required")
|
32
|
-
redirect_to edit_account_onboarding_user_detail_path(@user)
|
33
|
-
}
|
34
|
-
end
|
35
|
-
|
36
|
-
format.json { render :show, status: :ok, location: [:account, @user] }
|
37
|
-
else
|
38
|
-
|
39
|
-
# this is just checking whether the error on the email field is taking the email
|
40
|
-
# address is already taken.
|
41
|
-
@email_taken = begin
|
42
|
-
@user.errors.details[:email].select { |error| error[:error] == :taken }.any?
|
43
|
-
rescue
|
44
|
-
false
|
45
|
-
end
|
46
|
-
|
47
|
-
format.html { render :edit, status: :unprocessable_entity }
|
48
|
-
format.json { render json: @user.errors, status: :unprocessable_entity }
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
# Never trust parameters from the scary internet, only allow the white list through.
|
56
|
-
def user_params
|
57
|
-
params.require(:user).permit(
|
58
|
-
:email,
|
59
|
-
# 🚅 super scaffolding will insert new fields above this line.
|
60
|
-
# 🚅 super scaffolding will insert new arrays above this line.
|
61
|
-
)
|
62
|
-
|
63
|
-
# 🚅 super scaffolding will insert processing for new fields above this line.
|
64
|
-
end
|
2
|
+
include Account::Onboarding::UserEmail::ControllerBase
|
65
3
|
end
|
@@ -1,122 +1,3 @@
|
|
1
1
|
class Account::TeamsController < Account::ApplicationController
|
2
|
-
|
3
|
-
|
4
|
-
prepend_before_action do
|
5
|
-
if params["action"] == "new"
|
6
|
-
current_user.current_team = nil
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
before_action :enforce_invitation_only, only: [:create]
|
11
|
-
|
12
|
-
before_action do
|
13
|
-
# for magic locales.
|
14
|
-
@child_object = @team
|
15
|
-
end
|
16
|
-
|
17
|
-
# GET /teams
|
18
|
-
# GET /teams.json
|
19
|
-
def index
|
20
|
-
# if a user doesn't have multiple teams, we try to simplify the team ui/ux
|
21
|
-
# as much as possible. links to this page should go to the current team
|
22
|
-
# dashboard. however, some other links to this page are actually in branch
|
23
|
-
# logic and will not display at all. instead, users will be linked to the
|
24
|
-
# "new team" page. (see the main account sidebar menu for an example of
|
25
|
-
# this.)
|
26
|
-
unless current_user.multiple_teams?
|
27
|
-
redirect_to account_team_path(current_team)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# POST /teams/1/switch
|
32
|
-
def switch_to
|
33
|
-
current_user.current_team = @team
|
34
|
-
current_user.save
|
35
|
-
redirect_to account_dashboard_path
|
36
|
-
end
|
37
|
-
|
38
|
-
# GET /teams/1
|
39
|
-
# GET /teams/1.json
|
40
|
-
def show
|
41
|
-
# I don't think this is the best place to close the loop on the onboarding process, but practically speaking it's
|
42
|
-
# the easiest place to implement this at the moment, because all the onboarding steps redirect here on success.
|
43
|
-
if session[:after_onboarding_url].present?
|
44
|
-
redirect_to session.delete(:after_onboarding_url)
|
45
|
-
end
|
46
|
-
|
47
|
-
current_user.current_team = @team
|
48
|
-
current_user.save
|
49
|
-
end
|
50
|
-
|
51
|
-
# GET /teams/new
|
52
|
-
def new
|
53
|
-
render :new, layout: "devise"
|
54
|
-
end
|
55
|
-
|
56
|
-
# GET /teams/1/edit
|
57
|
-
def edit
|
58
|
-
end
|
59
|
-
|
60
|
-
# POST /teams
|
61
|
-
# POST /teams.json
|
62
|
-
def create
|
63
|
-
@team = Team.new(team_params)
|
64
|
-
|
65
|
-
respond_to do |format|
|
66
|
-
if @team.save
|
67
|
-
|
68
|
-
# also make the creator of the team the default admin.
|
69
|
-
@team.memberships.create(user: current_user, roles: [Role.admin])
|
70
|
-
|
71
|
-
current_user.current_team = @team
|
72
|
-
current_user.former_user = false
|
73
|
-
current_user.save
|
74
|
-
|
75
|
-
format.html { redirect_to [:account, @team], notice: I18n.t("teams.notifications.created") }
|
76
|
-
format.json { render :show, status: :created, location: [:account, @team] }
|
77
|
-
else
|
78
|
-
format.html { render :new, layout: "devise" }
|
79
|
-
format.json { render json: @team.errors, status: :unprocessable_entity }
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# PATCH/PUT /teams/1
|
85
|
-
# PATCH/PUT /teams/1.json
|
86
|
-
def update
|
87
|
-
respond_to do |format|
|
88
|
-
if @team.update(team_params)
|
89
|
-
format.html { redirect_to [:account, @team], notice: I18n.t("teams.notifications.updated") }
|
90
|
-
format.json { render :show, status: :ok, location: [:account, @team] }
|
91
|
-
else
|
92
|
-
format.html { render :edit, status: :unprocessable_entity }
|
93
|
-
format.json { render json: @team.errors, status: :unprocessable_entity }
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# # DELETE /teams/1
|
99
|
-
# # DELETE /teams/1.json
|
100
|
-
# def destroy
|
101
|
-
# @team.destroy
|
102
|
-
# respond_to do |format|
|
103
|
-
# format.html { redirect_to account_teams_url, notice: 'Team was successfully destroyed.' }
|
104
|
-
# format.json { head :no_content }
|
105
|
-
# end
|
106
|
-
# end
|
107
|
-
|
108
|
-
private
|
109
|
-
|
110
|
-
# Never trust parameters from the scary internet, only allow the white list through.
|
111
|
-
def team_params
|
112
|
-
params.require(:team).permit(
|
113
|
-
:name,
|
114
|
-
:time_zone,
|
115
|
-
:locale,
|
116
|
-
# 🚅 super scaffolding will insert new fields above this line.
|
117
|
-
# 🚅 super scaffolding will insert new arrays above this line.
|
118
|
-
)
|
119
|
-
|
120
|
-
# 🚅 super scaffolding will insert processing for new fields above this line.
|
121
|
-
end
|
2
|
+
include Account::Teams::ControllerBase
|
122
3
|
end
|
@@ -1,59 +1,3 @@
|
|
1
1
|
class Account::UsersController < Account::ApplicationController
|
2
|
-
|
3
|
-
|
4
|
-
before_action do
|
5
|
-
# for magic locales.
|
6
|
-
@child_object = @user
|
7
|
-
end
|
8
|
-
|
9
|
-
# GET /account/users/1/edit
|
10
|
-
def edit
|
11
|
-
end
|
12
|
-
|
13
|
-
# GET /account/users/1
|
14
|
-
def show
|
15
|
-
end
|
16
|
-
|
17
|
-
def updating_password?
|
18
|
-
params[:user].key?(:password)
|
19
|
-
end
|
20
|
-
|
21
|
-
# PATCH/PUT /account/users/1
|
22
|
-
# PATCH/PUT /account/users/1.json
|
23
|
-
def update
|
24
|
-
respond_to do |format|
|
25
|
-
if updating_password? ? @user.update_with_password(user_params) : @user.update_without_password(user_params)
|
26
|
-
# if you update your own user account, devise will normally kick you out, so we do this instead.
|
27
|
-
bypass_sign_in current_user.reload
|
28
|
-
format.html { redirect_to [:edit, :account, @user], notice: t("users.notifications.updated") }
|
29
|
-
format.json { render :show, status: :ok, location: [:account, @user] }
|
30
|
-
else
|
31
|
-
format.html { render :edit, status: :unprocessable_entity }
|
32
|
-
format.json { render json: @user.errors, status: :unprocessable_entity }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
# Never trust parameters from the scary internet, only allow the white list through.
|
40
|
-
def user_params
|
41
|
-
# TODO enforce permissions on updating the user's team name.
|
42
|
-
params.require(:user).permit(
|
43
|
-
:email,
|
44
|
-
:first_name,
|
45
|
-
:last_name,
|
46
|
-
:time_zone,
|
47
|
-
:current_password,
|
48
|
-
:password,
|
49
|
-
:password_confirmation,
|
50
|
-
:profile_photo_id,
|
51
|
-
:locale,
|
52
|
-
# 🚅 super scaffolding will insert new fields above this line.
|
53
|
-
current_team_attributes: [:name],
|
54
|
-
# 🚅 super scaffolding will insert new arrays above this line.
|
55
|
-
)
|
56
|
-
|
57
|
-
# 🚅 super scaffolding will insert processing for new fields above this line.
|
58
|
-
end
|
2
|
+
include Account::Users::ControllerBase
|
59
3
|
end
|