diff --git a/services/web/app/src/Features/Email/EmailBuilder.js b/services/web/app/src/Features/Email/EmailBuilder.js index db2beabbbf..f558f587ec 100644 --- a/services/web/app/src/Features/Email/EmailBuilder.js +++ b/services/web/app/src/Features/Email/EmailBuilder.js @@ -821,6 +821,87 @@ templates.SAMLDataCleared = ctaTemplate({ }, }) +templates.welcome = ctaTemplate({ + subject() { + return `Welcome to ${settings.appName}` + }, + title() { + return `Welcome to ${settings.appName}` + }, + greeting() { + return 'Hi,' + }, + message(opts, isPlainText) { + const logInAgainDisplay = EmailMessageHelper.displayLink( + 'log in again', + `${settings.siteUrl}/login`, + isPlainText + ) + const helpGuidesDisplay = EmailMessageHelper.displayLink( + 'Help Guides', + `${settings.siteUrl}/learn`, + isPlainText + ) + const templatesDisplay = EmailMessageHelper.displayLink( + 'Templates', + `${settings.siteUrl}/templates`, + isPlainText + ) + + return [ + `Thanks for signing up to ${settings.appName}! If you ever get lost, you can ${logInAgainDisplay} with the email address '${opts.to}'.`, + `If you're new to LaTeX, take a look at our ${helpGuidesDisplay} and ${templatesDisplay}.`, + `Please also take a moment to confirm your email address for ${settings.appName}:`, + ] + }, + secondaryMessage() { + return [ + `PS. We love talking to our users about ${settings.appName}. Reply to this email to get in touch with us directly, whatever the reason. Questions, comments, problems, suggestions, all welcome!`, + ] + }, + ctaText() { + return 'Confirm Email' + }, + ctaURL(opts) { + return opts.confirmEmailUrl + }, +}) + +templates.welcomeWithoutCTA = NoCTAEmailTemplate({ + subject() { + return `Welcome to ${settings.appName}` + }, + title() { + return `Welcome to ${settings.appName}` + }, + greeting() { + return 'Hi,' + }, + message(opts, isPlainText) { + const logInAgainDisplay = EmailMessageHelper.displayLink( + 'log in again', + `${settings.siteUrl}/login`, + isPlainText + ) + const helpGuidesDisplay = EmailMessageHelper.displayLink( + 'Help Guides', + `${settings.siteUrl}/learn`, + isPlainText + ) + const templatesDisplay = EmailMessageHelper.displayLink( + 'Templates', + `${settings.siteUrl}/templates`, + isPlainText + ) + + return [ + `Thanks for signing up to ${settings.appName}! If you ever get lost, you can ${logInAgainDisplay} with the email address '${opts.to}'.`, + `If you're new to LaTeX, take a look at our ${helpGuidesDisplay} and ${templatesDisplay}.`, + `PS. We love talking to our users about ${settings.appName}. Reply to this email to get in touch with us directly, whatever the reason. Questions, comments, problems, suggestions, all welcome!`, + ] + }, +}) + function _formatUserNameAndEmail(user, placeholder) { if (user.first_name && user.last_name) { const fullName = `${user.first_name} ${user.last_name}` diff --git a/services/web/app/src/infrastructure/Features.js b/services/web/app/src/infrastructure/Features.js index cdaf638c3d..ee77ac853d 100644 --- a/services/web/app/src/infrastructure/Features.js +++ b/services/web/app/src/infrastructure/Features.js @@ -1,9 +1,6 @@ const _ = require('lodash') const Settings = require('@overleaf/settings') -const publicRegistrationModuleAvailable = - Settings.moduleImportSequence.includes('public-registration') - const supportModuleAvailable = Settings.moduleImportSequence.includes('support') const symbolPaletteModuleAvailable = @@ -60,7 +57,7 @@ const Features = { Boolean(Settings.overleaf) ) case 'registration': - return publicRegistrationModuleAvailable || Boolean(Settings.overleaf) + return Boolean(Settings.overleaf) case 'github-sync': return Boolean(Settings.enableGithubSync) case 'git-bridge': @@ -89,8 +86,6 @@ const Features = { _.get(Settings, ['apis', 'linkedUrlProxy', 'url']) && Settings.enabledLinkedFileTypes.includes('url') ) - case 'public-registration': - return publicRegistrationModuleAvailable case 'support': return supportModuleAvailable case 'symbol-palette': diff --git a/services/web/test/acceptance/config/settings.test.defaults.js b/services/web/test/acceptance/config/settings.test.defaults.js index 2a1c3f0ff1..0a97b318d5 100644 --- a/services/web/test/acceptance/config/settings.test.defaults.js +++ b/services/web/test/acceptance/config/settings.test.defaults.js @@ -96,12 +96,6 @@ module.exports = { }, }, - // for registration via SL, set enableLegacyRegistration to true - // for registration via Overleaf v1, set enableLegacyLogin to true - - // Currently, acceptance tests require enableLegacyRegistration. - enableLegacyRegistration: true, - features: (features = { v1_free: { collaborators: 1, diff --git a/services/web/test/acceptance/src/RegistrationTests.js b/services/web/test/acceptance/src/RegistrationTests.js index 309335d949..e71fb6d331 100644 --- a/services/web/test/acceptance/src/RegistrationTests.js +++ b/services/web/test/acceptance/src/RegistrationTests.js @@ -396,7 +396,7 @@ describe('Registration', function () { expect(err).to.not.exist expect(body.redir != null).to.equal(false) expect(body.message != null).to.equal(true) - expect(body.message).to.have.all.keys('type', 'key') + expect(body.message).to.have.all.keys('type', 'text') expect(body.message.type).to.equal('error') cb() } diff --git a/services/web/test/unit/src/Email/EmailBuilderTests.js b/services/web/test/unit/src/Email/EmailBuilderTests.js index d06de2f09f..d9fdc1e97a 100644 --- a/services/web/test/unit/src/Email/EmailBuilderTests.js +++ b/services/web/test/unit/src/Email/EmailBuilderTests.js @@ -578,7 +578,58 @@ describe('EmailBuilder', function () { }) }) }) + + describe('welcome', function () { + beforeEach(function () { + this.emailAddress = 'example@overleaf.com' + this.opts = { + to: this.emailAddress, + confirmEmailUrl: `${this.settings.siteUrl}/user/emails/confirm?token=token123`, + } + this.email = this.EmailBuilder.buildEmail('welcome', this.opts) + this.dom = cheerio.load(this.email.html) + }) + + it('should build the email', function () { + expect(this.email.html).to.exist + expect(this.email.text).to.exist + }) + + describe('HTML email', function () { + it('should include a CTA button and a fallback CTA link', function () { + const buttonLink = this.dom('a:contains("Confirm Email")') + expect(buttonLink.length).to.equal(1) + expect(buttonLink.attr('href')).to.equal(this.opts.confirmEmailUrl) + const fallback = this.dom('.force-overleaf-style').last() + expect(fallback.length).to.equal(1) + expect(fallback.html()).to.contain(this.opts.confirmEmailUrl) + }) + it('should include help links', function () { + const helpGuidesLink = this.dom('a:contains("Help Guides")') + const templatesLink = this.dom('a:contains("Templates")') + const logInLink = this.dom('a:contains("log in")') + expect(helpGuidesLink.length).to.equal(1) + expect(templatesLink.length).to.equal(1) + expect(logInLink.length).to.equal(1) + }) + }) + + describe('plain text email', function () { + it('should contain the CTA URL', function () { + expect(this.email.text).to.contain(this.opts.confirmEmailUrl) + }) + it('should include help URL', function () { + expect(this.email.text).to.contain('/learn') + expect(this.email.text).to.contain('/login') + expect(this.email.text).to.contain('/templates') + }) + it('should contain HTML links', function () { + expect(this.email.text).to.not.contain('