From 20898db17f75051ac0b1ad3ec7b1a7c001ffc0b7 Mon Sep 17 00:00:00 2001 From: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> Date: Tue, 24 Feb 2026 17:11:14 +0200 Subject: [PATCH] Merge pull request #31560 from overleaf/ii-domain-capture-multiple-groups [web] Multiple captured domains GitOrigin-RevId: c097688efed82a8de11233078134923ed23bf500 --- .../app/src/Features/Project/ProjectController.mjs | 12 ++++++++---- .../src/Features/Project/ProjectListController.mjs | 12 ++++++++---- services/web/frontend/extracted-translations.json | 4 ++++ services/web/frontend/js/utils/meta.ts | 4 ++++ services/web/locales/en.json | 3 +++ .../test/unit/src/Project/ProjectController.test.mjs | 10 ++++++++-- .../unit/src/Project/ProjectListController.test.mjs | 10 ++++++++-- 7 files changed, 43 insertions(+), 12 deletions(-) diff --git a/services/web/app/src/Features/Project/ProjectController.mjs b/services/web/app/src/Features/Project/ProjectController.mjs index 18a3288d0b..c6e5355b38 100644 --- a/services/web/app/src/Features/Project/ProjectController.mjs +++ b/services/web/app/src/Features/Project/ProjectController.mjs @@ -404,15 +404,19 @@ const _ProjectController = { ) if (domainCaptureRedirect === 'enabled') { - const subscription = ( + const groupsWithEmails = ( await Modules.promises.hooks.fire( - 'findDomainCaptureGroupUserCouldBePartOf', + 'findDomainCaptureGroupsUserCouldBePartOf', userId ) )?.[0] - if (subscription) { - if (subscription.managedUsersEnabled) { + if (groupsWithEmails && groupsWithEmails.length > 0) { + if ( + groupsWithEmails.some( + ({ subscription }) => subscription.managedUsersEnabled + ) + ) { return res.redirect('/domain-capture') } else { // TODO show notification or anything else diff --git a/services/web/app/src/Features/Project/ProjectListController.mjs b/services/web/app/src/Features/Project/ProjectListController.mjs index 707b68c596..a3a677e710 100644 --- a/services/web/app/src/Features/Project/ProjectListController.mjs +++ b/services/web/app/src/Features/Project/ProjectListController.mjs @@ -143,15 +143,19 @@ async function projectListPage(req, res, next) { ) if (domainCaptureRedirect === 'enabled') { - const subscription = ( + const groupsWithEmails = ( await Modules.promises.hooks.fire( - 'findDomainCaptureGroupUserCouldBePartOf', + 'findDomainCaptureGroupsUserCouldBePartOf', userId ) )?.[0] - if (subscription) { - if (subscription.managedUsersEnabled) { + if (groupsWithEmails && groupsWithEmails.length > 0) { + if ( + groupsWithEmails.some( + ({ subscription }) => subscription.managedUsersEnabled + ) + ) { return res.redirect('/domain-capture') } else { // TODO show notification or anything else diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index acc0d8e13f..f59b6e3a36 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -1335,6 +1335,7 @@ "please_reconfirm_institutional_email": "", "please_reconfirm_your_affiliation_before_making_this_primary": "", "please_refresh": "", + "please_remove_all_emails": "", "please_select": "", "please_select_a_file": "", "please_select_a_project": "", @@ -2257,6 +2258,7 @@ "you_are_a_manager_of_publisher_x": "", "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z": "", "you_are_a_manager_of_x_plan_as_member_of_group_subscription_y_administered_by_z_you": "", + "you_are_currently_logged_in_as": "", "you_are_on_a_paid_plan_contact_support_to_find_out_more": "", "you_are_on_x_plan_as_a_confirmed_member_of_institution_y": "", "you_are_on_x_plan_as_member_of_group_subscription_y_administered_by_z": "", @@ -2267,6 +2269,7 @@ "you_can_now_enable_sso": "", "you_can_now_log_in_sso": "", "you_can_now_search_and_add_references_from_your_rm_library_without_needing_to_import_files": "", + "you_can_only_be_affiliated_with_one_group": "", "you_can_request_a_maximum_of_limit_fixes_per_day": "", "you_can_select_or_invite_collaborator": "", "you_can_select_or_invite_collaborator_plural": "", @@ -2282,6 +2285,7 @@ "you_have_been_invited_to_transfer_management_of_your_account": "", "you_have_been_invited_to_transfer_management_of_your_account_to": "", "you_have_been_removed_from_this_project_and_will_be_redirected_to_project_dashboard": "", + "you_have_multiple_organization_email_addresses_on_your_account": "", "you_have_x_licenses_and_your_plan_supports_up_to_y": "", "you_have_x_licenses_on_your_subscription": "", "you_need_to_configure_your_sso_settings": "", diff --git a/services/web/frontend/js/utils/meta.ts b/services/web/frontend/js/utils/meta.ts index 88bd544a36..64b9016210 100644 --- a/services/web/frontend/js/utils/meta.ts +++ b/services/web/frontend/js/utils/meta.ts @@ -28,6 +28,7 @@ import { Tag } from '../../../app/src/Features/Tags/types' import { Institution } from '../../../types/institution' import { GroupPolicy, + GroupSubscription, ManagedGroupSubscription, MemberGroupSubscription, StripePaymentProviderService, @@ -206,6 +207,9 @@ export interface Meta { 'ol-memberGroupSubscriptions': MemberGroupSubscription[] 'ol-memberOfSSOEnabledGroups': GroupSSOLinkingStatus[] 'ol-members': MinimalUser[] + 'ol-multiple-group-subscriptions': Array< + Pick & { id: string; email: string } + > 'ol-navbar': DefaultNavbarMetadata 'ol-newsletter-subscribed': boolean 'ol-no-single-dollar': boolean diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 30569e8058..8083813949 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -1740,6 +1740,7 @@ "please_reconfirm_institutional_email_2": "Please take a moment to confirm your institutional email address or remove it from your account.", "please_reconfirm_your_affiliation_before_making_this_primary": "Please confirm your affiliation before making this the primary.", "please_refresh": "Please refresh the page to continue.", + "please_remove_all_emails": "Please remove all emails except for the email associated with the organization which you would like to join, or remove all organization emails if you would like to keep this account personal.", "please_request_a_new_password_reset_email_and_follow_the_link": "Please request a new password reset email and follow the link", "please_select": "Please select", "please_select_a_file": "Please Select a File", @@ -2833,6 +2834,7 @@ "you_can_now_log_in_sso": "You can now log in through your institution and if eligible you will receive <0>__appName__ Professional features.", "you_can_now_search_and_add_references_from_your_rm_library_without_needing_to_import_files": "You can now search and add references from your __referenceManager__ library without needing to import files—just type \\cite{} in your .tex file. Learn more", "you_can_now_sign_in_with_new_password": "You can now sign in with your new password.", + "you_can_only_be_affiliated_with_one_group": "You can only be affiliated with one group.", "you_can_opt_in_and_out_of_the_program_at_any_time_on_this_page": "You can <0>opt in and out of the program at any time on this page", "you_can_request_a_maximum_of_limit_fixes_per_day": "You can request a maximum of __limit__ fixes per day. Please try again tomorrow.", "you_can_select_or_invite_collaborator": "You can select or invite __count__ collaborator on your current plan. Upgrade to add more editors or reviewers.", @@ -2850,6 +2852,7 @@ "you_have_been_invited_to_transfer_management_of_your_account": "You have been invited to transfer management of your account.", "you_have_been_invited_to_transfer_management_of_your_account_to": "You have been invited to transfer management of your account to __groupName__.", "you_have_been_removed_from_this_project_and_will_be_redirected_to_project_dashboard": "You have been removed from this project, and will no longer have access to it. You will be redirected to your project dashboard momentarily.", + "you_have_multiple_organization_email_addresses_on_your_account": "You have multiple organization email addresses on your account that have group subscriptions on __appName__.", "you_have_x_licenses_and_your_plan_supports_up_to_y": "You have allocated __addedUsersSize__ licenses and your plan supports up to __groupSize__.", "you_have_x_licenses_on_your_subscription": "You have __groupSize__ licenses on your subscription.", "you_need_to_configure_your_sso_settings": "You need to configure and test your SSO settings before enabling SSO", diff --git a/services/web/test/unit/src/Project/ProjectController.test.mjs b/services/web/test/unit/src/Project/ProjectController.test.mjs index 8efd854dd5..ee4fa2d0c2 100644 --- a/services/web/test/unit/src/Project/ProjectController.test.mjs +++ b/services/web/test/unit/src/Project/ProjectController.test.mjs @@ -868,8 +868,14 @@ describe('ProjectController', function () { .withArgs(ctx.req, ctx.res, 'domain-capture-redirect') .resolves({ variant: 'enabled' }) ctx.Modules.promises.hooks.fire - .withArgs('findDomainCaptureGroupUserCouldBePartOf', ctx.user._id) - .resolves([{ _id: new ObjectId(), managedUsersEnabled: true }]) + .withArgs('findDomainCaptureGroupsUserCouldBePartOf', ctx.user._id) + .resolves([ + [ + { + subscription: { managedUsersEnabled: true }, + }, + ], + ]) await new Promise(resolve => { ctx.res.redirect = url => { url.should.equal('/domain-capture') diff --git a/services/web/test/unit/src/Project/ProjectListController.test.mjs b/services/web/test/unit/src/Project/ProjectListController.test.mjs index a68ec84c46..a7831ab3ed 100644 --- a/services/web/test/unit/src/Project/ProjectListController.test.mjs +++ b/services/web/test/unit/src/Project/ProjectListController.test.mjs @@ -522,8 +522,14 @@ describe('ProjectListController', function () { .withArgs(ctx.req, ctx.res, 'domain-capture-redirect') .resolves({ variant: 'enabled' }) ctx.Modules.promises.hooks.fire - .withArgs('findDomainCaptureGroupUserCouldBePartOf', ctx.user._id) - .resolves([{ _id: new ObjectId(), managedUsersEnabled: true }]) + .withArgs('findDomainCaptureGroupsUserCouldBePartOf', ctx.user._id) + .resolves([ + [ + { + subscription: { managedUsersEnabled: true }, + }, + ], + ]) ctx.res.redirect = url => { url.should.equal('/domain-capture') }