Scope member invite links under the organization path
What does this MR do and why?
Generates member invitation links scoped under the inviting organization's path — /o/<organization_path>/-/invites/<token> — for non-default (Cells) organizations, instead of the global /-/invites/<token>.
Cells Path-Based Routing already routes /o/<organization_path>/* to the cell that owns the organization, so an org-scoped invite link lands on the correct cell without the HTTP Router having to route on, hash, or claim the raw invite token. This avoids sharing secret_key_base with the edge router and sidesteps the routable-token migration that token-based routing would otherwise require.
Changes:
- Add
InvitesHelperwithinvite_url_for/accept_invite_url_for/decline_invite_url_for. These call the standard route helpers;Routing::OrganizationsHelper::MappedHelperstransparently dispatches them to the/o/:organization_path/-/invites/...routes when anorganization_pathis supplied. - Wire the helper into the invite mailers (
Members::InviteMailer,Members::InviteReminderMailer) and the corresponding views (invites/show, mailer templates). - Scoping applies only when the organization serves scoped paths (
scoped_paths?, i.e. non-default) and theorganization_scoped_invite_linksflag is enabled. Default-organization behavior is unchanged, so we never emit/o/default/....
Behind the organization_scoped_invite_links feature flag (gitlab_com_derisk, default disabled).
References
Screenshots or screen recordings
No visual UI change. The only user-visible difference is the host/path of the invite link in invitation emails and the accept/decline links on the invite page.
| Before | After |
|---|---|
https://gitlab.com/-/invites/<token> |
https://gitlab.com/o/<organization_path>/-/invites/<token> |
How to set up and validate locally
-
Enable the flag for a non-default organization in the Rails console:
org = Organizations::Organization.find_by(path: '<your-org-path>') # a non-default org Feature.enable(:organization_scoped_invite_links, org) -
Invite a member by email to a group/project owned by that organization (e.g.
http://gdk.test:3000/groups/<group>/-/group_members→ Invite members). -
Check the generated invitation email via
gdk.test:3000/rails/letter_opener- the invite/accept/decline links should be prefixed with/o/<organization_path>/-/invites/.... -
Repeat for a group in the default organization (or with the flag off) and confirm the links remain the global
/-/invites/....
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.