1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# frozen_string_literal: true
class InvitesController < ApplicationController
include Gitlab::Utils::StrongMemoize
prepend_before_action :authenticate_user!, :track_invite_join_click, only: :show
before_action :member
before_action :ensure_member_exists
before_action :invite_details
skip_before_action :authenticate_user!, only: :decline
helper_method :member?, :current_user_matches_invite?
respond_to :html
feature_category :authentication_and_authorization
def show
accept if skip_invitation_prompt?
end
def accept
if current_user_matches_invite? && member.accept_invite!(current_user)
redirect_to invite_details[:path], notice: helpers.invite_accepted_notice(member)
else
redirect_back_or_default(options: { alert: _("The invitation could not be accepted.") })
end
end
def decline
if member.decline_invite!
return render layout: 'signup_onboarding' if !current_user && member.invite_to_unknown_user? && member.created_by
path =
if current_user
dashboard_projects_path
else
new_user_session_path
end
redirect_to path, notice: _("You have declined the invitation to join %{title} %{name}.") %
{ title: invite_details[:title], name: invite_details[:name] }
else
redirect_back_or_default(options: { alert: _("The invitation could not be declined.") })
end
end
private
def skip_invitation_prompt?
!member? && current_user_matches_invite?
end
def current_user_matches_invite?
current_user.verified_emails.include?(@member.invite_email)
end
def member?
strong_memoize(:is_member) do
@member.source.users.include?(current_user)
end
end
def member
strong_memoize(:member) do
@token = params[:id]
Member.find_by_invite_token(@token)
end
end
def ensure_member_exists
return if member
redirect_back_or_default(options: { alert: _("The invitation can not be found with the provided invite token.") })
end
def track_invite_join_click
return unless member && initial_invite_email?
experiment(:invite_email_preview_text, actor: member).track(:join_clicked) if params[:experiment_name] == 'invite_email_preview_text'
Gitlab::Tracking.event(self.class.name, 'join_clicked', label: 'invite_email', property: member.id.to_s)
end
def authenticate_user!
return if current_user
store_location_for(:user, invite_landing_url) if member
if user_sign_up?
set_session_invite_params
redirect_to new_user_registration_path(invite_email: member.invite_email), notice: _("To accept this invitation, create an account or sign in.")
else
redirect_to new_user_session_path(sign_in_redirect_params), notice: sign_in_notice
end
end
def set_session_invite_params
session[:invite_email] = member.invite_email
session[:originating_member_id] = member.id if initial_invite_email?
session[:invite_email_experiment_name] = params[:experiment_name] if initial_invite_email? && params[:experiment_name]
end
def initial_invite_email?
params[:invite_type] == Emails::Members::INITIAL_INVITE
end
def sign_in_redirect_params
member ? { invite_email: member.invite_email } : {}
end
def user_sign_up?
Gitlab::CurrentSettings.allow_signup? && member && !User.find_by_any_email(member.invite_email)
end
def sign_in_notice
if Gitlab::CurrentSettings.allow_signup?
_("To accept this invitation, sign in or create an account.")
else
_("To accept this invitation, sign in.")
end
end
def invite_landing_url
root_url + invite_details[:path]
end
def invite_details
@invite_details ||= case member.source
when Project
{
name: member.source.full_name,
url: project_url(member.source),
title: _("project"),
path: member.source.activity_path
}
when Group
{
name: member.source.name,
url: group_url(member.source),
title: _("group"),
path: member.source.activity_path
}
end
end
end
|