diff --git a/services/web/app/src/Features/Email/EmailBuilder.mjs b/services/web/app/src/Features/Email/EmailBuilder.mjs index f87f5903f8..3de026eb6d 100644 --- a/services/web/app/src/Features/Email/EmailBuilder.mjs +++ b/services/web/app/src/Features/Email/EmailBuilder.mjs @@ -1040,6 +1040,36 @@ templates.groupMemberLimitWarning = ctaTemplate({ }, }) +templates.groupDomainCapturedByGroupChanged = ctaTemplate({ + subject(opts) { + return opts.domainCapturedByGroup + ? `Domain capture now active for ${opts.domain}` + : `Domain capture now inactive for ${opts.domain}` + }, + title(opts) { + return opts.domainCapturedByGroup + ? `Domain capture is active for ${_.escape(opts.domain)}` + : `Domain capture is inactive for ${_.escape(opts.domain)}` + }, + message(opts) { + if (opts.domainCapturedByGroup) { + return [ + `Users with a ${_.escape(opts.domain)} email address on their account will be able to join your group through domain capture.`, + ] + } + return [ + `Users with a ${_.escape(opts.domain)} email address on their account will no longer be able to join your group through domain capture. Anyone already in your group is unaffected.`, + `If you didn't expect this or want to re-enable it, please contact ${settings.adminEmail}.`, + ] + }, + ctaText() { + return 'Manage domains' + }, + ctaURL(opts) { + return `${settings.siteUrl}/manage/groups/${opts.groupId}/settings` + }, +}) + function _formatUserNameAndEmail(user, placeholder) { if (user.first_name && user.last_name) { const fullName = `${user.first_name} ${user.last_name}` diff --git a/services/web/test/unit/src/Email/EmailBuilder.test.mjs b/services/web/test/unit/src/Email/EmailBuilder.test.mjs index 7e8843f705..508c59fe7f 100644 --- a/services/web/test/unit/src/Email/EmailBuilder.test.mjs +++ b/services/web/test/unit/src/Email/EmailBuilder.test.mjs @@ -14,6 +14,7 @@ describe('EmailBuilder', function () { ctx.settings = { appName: 'testApp', siteUrl: 'https://www.overleaf.com', + adminEmail: 'admin@overleaf.test', } vi.doMock('../../../../app/src/Features/Email/EmailMessageHelper', () => ({ @@ -963,6 +964,50 @@ describe('EmailBuilder', function () { }) }) }) + + describe('groupDomainCapturedByGroupChanged', function () { + it('should build active-domain-capture email', function (ctx) { + const email = ctx.EmailBuilder.buildEmail( + 'groupDomainCapturedByGroupChanged', + { + to: 'admin@example.com', + groupId: 'group-123', + domainCapturedByGroup: true, + domain: 'example.com', + } + ) + + expect(email.subject).to.equal( + 'Domain capture now active for example.com' + ) + expect(email.html).to.contain( + 'Domain capture is active for example.com' + ) + expect(email.html).to.contain('/manage/groups/group-123/settings') + expect(email.text).to.contain('/manage/groups/group-123/settings') + }) + + it('should build inactive-domain-capture email including support contact', function (ctx) { + const email = ctx.EmailBuilder.buildEmail( + 'groupDomainCapturedByGroupChanged', + { + to: 'admin@example.com', + groupId: 'group-123', + domainCapturedByGroup: false, + domain: 'example.com', + } + ) + + expect(email.subject).to.equal( + 'Domain capture now inactive for example.com' + ) + expect(email.html).to.contain( + 'Domain capture is inactive for example.com' + ) + expect(email.html).to.contain('admin@overleaf.test') + expect(email.text).to.contain('admin@overleaf.test') + }) + }) }) }) })