Skip to content

Commit 3173a6a

Browse files
committed
Refactor community membership creation to use find_or_create_by for event invitations and registrations
1 parent e062049 commit 3173a6a

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

app/controllers/better_together/events_controller.rb

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,28 @@ def authorize_resource
118118

119119
# Helper method to find invitation by token
120120
def find_invitation_by_token
121-
return nil unless current_invitation_token.present?
121+
# Prefer explicit token param (fresh request) and fall back to the current token
122+
token = params[:invitation_token].presence || params[:token].presence || current_invitation_token
123+
return nil unless token.present?
124+
125+
# Try to scope the invitation to the current event when possible
126+
invitation = if @event
127+
BetterTogether::EventInvitation.pending.not_expired.find_by(token: token, invitable: @event)
128+
else
129+
BetterTogether::EventInvitation.pending.not_expired.find_by(token: token)
130+
end
131+
132+
# If token came in params and invitation is valid for this event, persist it in session
133+
if invitation && (params[:invitation_token].present? || params[:token].present?)
134+
session[:event_invitation_token] = invitation.token
135+
session[:event_invitation_expires_at] = 24.hours.from_now
136+
I18n.locale = invitation.locale if invitation.locale.present?
137+
session[:locale] = I18n.locale
138+
# ensure the authorization concern sees the most recent token
139+
set_current_invitation_token(invitation.token)
140+
end
122141

123-
BetterTogether::EventInvitation.find_by(
124-
token: current_invitation_token,
125-
invitable: @event
126-
)
142+
invitation
127143
end
128144

129145
# Process event invitation tokens before inherited (ApplicationController) callbacks
@@ -138,19 +154,35 @@ def check_platform_privacy
138154
# If host platform is public or user is signed in, let ApplicationController handle it
139155
return super if helpers.host_platform.privacy_public? || current_user.present?
140156

141-
token = params[:invitation_token].presence || params[:token].presence
157+
# Consider explicit params token first, then session-stored event tokens
158+
token = params[:invitation_token].presence || params[:token].presence || session[:event_invitation_token].presence
142159
if token.present? && params[:id].present?
160+
# Find any invitation by token (including expired) so we can distinguish expired vs non-existent
161+
invitation_any = ::BetterTogether::EventInvitation.find_by(token: token)
162+
163+
# If no invitation exists at all, treat as no valid token -> fall back to ApplicationController (redirect to login)
164+
return super unless invitation_any.present?
165+
166+
# If an invitation exists but is not valid (expired or not pending), fall back to ApplicationController
167+
expired = invitation_any.valid_until.present? && Time.current > invitation_any.valid_until
168+
return super unless invitation_any.pending? && !expired
169+
170+
# Now find a valid, pending, not-expired invitation scoped to this event
143171
invitation = ::BetterTogether::EventInvitation.pending.not_expired.find_by(token: token)
144-
if invitation
145-
# Valid invitation: set locale and allow access
172+
if invitation && invitation.invitable.present? && invitation.invitable.slug == params[:id]
173+
# Valid invitation for this event: persist token, set locale and allow access
174+
session[:event_invitation_token] = invitation.token
175+
session[:event_invitation_expires_at] = 24.hours.from_now
146176
I18n.locale = invitation.locale if invitation.locale.present?
147177
session[:locale] = I18n.locale
178+
# ensure the authorization concern sees the most recent token
179+
set_current_invitation_token(invitation.token)
148180
return true
149-
else
150-
# Invalid token for this event on a private platform: render 404
151-
render_not_found
152-
return
153181
end
182+
183+
# Invitation exists but does not match this event -> render 404
184+
render_not_found
185+
return
154186
end
155187

156188
# Fall back to ApplicationController implementation for other cases

app/controllers/better_together/users/registrations_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def create # rubocop:todo Metrics/MethodLength, Metrics/AbcSize
9999
# Handle community membership based on invitation type
100100
community_role = determine_community_role
101101

102-
helpers.host_community.person_community_memberships.create!(
102+
helpers.host_community.person_community_memberships.find_or_create_by!(
103103
member: user.person,
104104
role: community_role
105105
)

app/models/better_together/event_invitation.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def ensure_community_membership!(person)
121121

122122
# Create community membership for the invitee
123123
default_role = BetterTogether::Role.find_by(identifier: 'community_member')
124-
community.person_community_memberships.create!(
124+
community.person_community_memberships.find_or_create_by!(
125125
member: person,
126126
role: default_role
127127
)

0 commit comments

Comments
 (0)