diff --git a/services/web/app/src/Features/Project/ProjectListController.mjs b/services/web/app/src/Features/Project/ProjectListController.mjs index 747ef04ba7..27cff0343a 100644 --- a/services/web/app/src/Features/Project/ProjectListController.mjs +++ b/services/web/app/src/Features/Project/ProjectListController.mjs @@ -319,7 +319,9 @@ async function projectListPage(req, res, next) { institutionName: samlSession.linked.universityName || samlSession.linked.providerName, - templateKey: 'notification_institution_sso_linked', + templateKey: samlSession.domainCaptureEnabled + ? 'notification_group_sso_linked' + : 'notification_institution_sso_linked', }) } diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index c9b9791c78..a7d66badaf 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -50,6 +50,7 @@ "access_edit_your_projects": "", "access_levels_changed": "", "account_billed_manually": "", + "account_has_been_link_to_group_account": "", "account_has_been_link_to_institution_account": "", "account_has_past_due_invoice_change_plan_warning": "", "account_help": "", diff --git a/services/web/frontend/js/features/project-list/components/notifications/groups/institution.tsx b/services/web/frontend/js/features/project-list/components/notifications/groups/institution.tsx index c06b9cb3d1..5fc53c7d4b 100644 --- a/services/web/frontend/js/features/project-list/components/notifications/groups/institution.tsx +++ b/services/web/frontend/js/features/project-list/components/notifications/groups/institution.tsx @@ -88,6 +88,21 @@ function Institution() { } /> )} + {templateKey === 'notification_group_sso_linked' && ( + id && handleDismiss(id)} + content={ + }} + values={{ appName, email, institutionName }} + shouldUnescape + tOptions={{ interpolation: { escapeValue: true } }} + /> + } + /> + )} {templateKey === 'notification_institution_sso_non_canonical' && ( __email__ has been linked to your __institutionName__ account.", "account_has_been_link_to_institution_account": "Your __appName__ account on __email__ has been linked to your __institutionName__ institutional account.", "account_has_past_due_invoice_change_plan_warning": "Your account currently has a past due invoice. You will not be able to change your plan until this is resolved.", "account_help": "Account and help", diff --git a/services/web/test/frontend/features/project-list/components/notifications.test.tsx b/services/web/test/frontend/features/project-list/components/notifications.test.tsx index e0c0ba40df..e763d4d852 100644 --- a/services/web/test/frontend/features/project-list/components/notifications.test.tsx +++ b/services/web/test/frontend/features/project-list/components/notifications.test.tsx @@ -509,8 +509,43 @@ describe('', function () { render() fetchMock.delete(`/notifications/${institution._id}`, 200) - screen.getByRole('alert') - screen.getByText(/has been linked to your/i) + const notificationEl = screen.getByRole('alert') + expect(notificationEl.textContent).to.match( + new RegExp( + `your Overleaf account on ${notificationsInstitution.email} ` + + `has been linked to your ${notificationsInstitution.institutionName} ` + + `institutional account.`, + 'i' + ) + ) + + const closeBtn = screen.getByRole('button', { name: /close/i }) + fireEvent.click(closeBtn) + + expect(fetchMock.callHistory.called()).to.be.true + expect(screen.queryByRole('alert')).to.be.null + }) + + it('shows sso linked to group with domain capture enabled', function () { + const institution: DeepPartial = { + _id: 1, + templateKey: 'notification_group_sso_linked', + } + window.metaAttributesCache.set('ol-notificationsInstitution', [ + { ...notificationsInstitution, ...institution }, + ]) + render() + fetchMock.delete(`/notifications/${institution._id}`, 200) + + const notificationEl = screen.getByRole('alert') + expect(notificationEl.textContent).to.match( + new RegExp( + `your Overleaf account on ${notificationsInstitution.email} ` + + `has been linked to your ${notificationsInstitution.institutionName} ` + + `account.`, + 'i' + ) + ) const closeBtn = screen.getByRole('button', { name: /close/i }) fireEvent.click(closeBtn) diff --git a/services/web/test/unit/src/Project/ProjectListController.test.mjs b/services/web/test/unit/src/Project/ProjectListController.test.mjs index 717f39ff18..28bb6b67ec 100644 --- a/services/web/test/unit/src/Project/ProjectListController.test.mjs +++ b/services/web/test/unit/src/Project/ProjectListController.test.mjs @@ -570,7 +570,25 @@ describe('ProjectListController', function () { } ctx.ProjectListController.projectListPage(ctx.req, ctx.res) }) - it('should show a linked group notification via domain capture', function (ctx) { + it('should show a group linked notification when domain capture enabled', function (ctx) { + ctx.req.session.saml = { + institutionEmail: ctx.institutionEmail, + linked: { + hasEntitlement: false, + universityName: ctx.institutionName, + }, + domainCaptureEnabled: true, + } + ctx.res.render = (pageName, opts) => { + expect(opts.notificationsInstitution).to.deep.include({ + email: ctx.institutionEmail, + institutionName: ctx.institutionName, + templateKey: 'notification_group_sso_linked', + }) + } + ctx.ProjectListController.projectListPage(ctx.req, ctx.res) + }) + it('should show a success notification when joining group via domain capture page', function (ctx) { ctx.req.session.saml = { linkedGroup: true, universityName: ctx.institutionName,