diff --git a/.env.sample b/.env.sample index 98b69fda4..ff475682a 100644 --- a/.env.sample +++ b/.env.sample @@ -13,3 +13,9 @@ URL=http://localhost:3000 DEPLOYMENT=hosted ENABLE_UPDATES=true GOOGLE_ANALYTICS_ID= + +SMTP_HOST= +SMTP_PORT= +SMTP_USERNAME= +SMTP_PASSWORD= +SMTP_SENDER_EMAIL= \ No newline at end of file diff --git a/circle.yml b/circle.yml index 99947a857..4ddaf4502 100644 --- a/circle.yml +++ b/circle.yml @@ -9,6 +9,8 @@ machine: SECRET_KEY: F0E5AD933D7F6FD8F4DBB3E038C501C052DC0593C686D21ACB30AE205D2F634B DATABASE_URL_TEST: postgres://ubuntu@localhost:5432/circle_test DATABASE_URL: postgres://ubuntu@localhost:5432/circle_test + URL: http://localhost:3000 + SMTP_SENDER_EMAIL: hello@example.com dependencies: override: diff --git a/package.json b/package.json index 9ce26ca3f..3830fa0d1 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,8 @@ "main": "index.js", "scripts": { "clean": "rimraf dist", - "build:webpack": - "NODE_ENV=production webpack --config webpack.config.prod.js", - "build:analyze": - "NODE_ENV=production webpack --config webpack.config.prod.js --json | webpack-bundle-size-analyzer", + "build:webpack": "NODE_ENV=production webpack --config webpack.config.prod.js", + "build:analyze": "NODE_ENV=production webpack --config webpack.config.prod.js --json | webpack-bundle-size-analyzer", "build": "npm run clean && npm run build:webpack", "start": "NODE_ENV=production node index.js", "dev": "NODE_ENV=development nodemon --inspect --watch server index.js", @@ -20,24 +18,39 @@ "sequelize:migrate": "sequelize db:migrate", "test": "npm run test:app && npm run test:server", "test:app": "jest", - "test:server": - "jest --config=server/.jestconfig.json --runInBand --forceExit", + "test:server": "jest --config=server/.jestconfig.json --runInBand --forceExit", "precommit": "lint-staged" }, "lint-staged": { - "*.js": ["eslint --fix", "git add"] + "*.js": [ + "eslint --fix", + "git add" + ] }, "jest": { "verbose": false, - "roots": ["app"], + "roots": [ + "app" + ], "moduleNameMapper": { "^.*[.](s?css|css)$": "/__mocks__/styleMock.js", "^.*[.](gif|ttf|eot|svg)$": "/__test__/fileMock.js" }, - "moduleFileExtensions": ["js", "jsx", "json"], - "moduleDirectories": ["node_modules"], - "modulePaths": ["app"], - "setupFiles": ["/setupJest.js", "/__mocks__/window.js"] + "moduleFileExtensions": [ + "js", + "jsx", + "json" + ], + "moduleDirectories": [ + "node_modules" + ], + "modulePaths": [ + "app" + ], + "setupFiles": [ + "/setupJest.js", + "/__mocks__/window.js" + ] }, "engines": { "node": ">= 7.6" @@ -117,8 +130,10 @@ "mobx-react-devtools": "^4.2.11", "moment": "2.13.0", "node-dev": "3.1.0", + "nodemailer": "^4.4.0", "normalize.css": "^7.0.0", "normalizr": "2.0.1", + "oy-vey": "^0.10.0", "pg": "^6.1.5", "pg-hstore": "2.3.2", "polished": "1.2.1", diff --git a/server/__snapshots__/mailer.test.js.snap b/server/__snapshots__/mailer.test.js.snap new file mode 100644 index 000000000..39ad09173 --- /dev/null +++ b/server/__snapshots__/mailer.test.js.snap @@ -0,0 +1,66 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Mailer #welcome 1`] = ` +Object { + "from": "hello@example.com", + "html": " + + + + + + + + Welcome to Outline + + + + + + + + + + +
+ Outline is a place for your team to build and share knowledge. +
 

Welcome to Outline!

Outline is a place for your team to build and share knowledge.

To get started, head to your dashboard and try creating a collection to help document your workflow, create playbooks or help with team onboarding.

You can also import existing Markdown document by drag and dropping them to your collections

 

View my dashboard

 
Outline
+
+ + + ", + "subject": "Welcome to Outline", + "text": " +Welcome to Outline! + +Outline is a place for your team to build and share knowledge. + +To get started, head to your dashboard and try creating a collection to help document your workflow, create playbooks or help with team onboarding. + +You can also import existing Markdown document by drag and dropping them to your collections + +http://localhost:3000/dashboard +", + "to": "user@example.com", +} +`; diff --git a/server/api/auth.test.js b/server/api/auth.test.js index 5da560065..202e5ee9f 100644 --- a/server/api/auth.test.js +++ b/server/api/auth.test.js @@ -10,6 +10,12 @@ afterAll(server.close); describe.skip('#auth.signup', async () => { it('should signup a new user', async () => { + const welcomeEmailMock = jest.fn(); + jest.doMock('../mailer', () => { + return { + welcome: welcomeEmailMock, + }; + }); const res = await server.post('/api/auth.signup', { body: { username: 'testuser', @@ -23,6 +29,7 @@ describe.skip('#auth.signup', async () => { expect(res.status).toEqual(200); expect(body.ok).toBe(true); expect(body.data.user).toBeTruthy(); + expect(welcomeEmailMock).toBeCalledWith('new.user@example.com'); }); it('should require params', async () => { diff --git a/server/emails/WelcomeEmail.js b/server/emails/WelcomeEmail.js new file mode 100644 index 000000000..4cf4b96ce --- /dev/null +++ b/server/emails/WelcomeEmail.js @@ -0,0 +1,52 @@ +// @flow +import React from 'react'; +import EmailTemplate from './components/EmailLayout'; +import Body from './components/Body'; +import Button from './components/Button'; +import Footer from './components/Footer'; +import EmptySpace from './components/EmptySpace'; + +export const welcomeEmailText = ` +Welcome to Outline! + +Outline is a place for your team to build and share knowledge. + +To get started, head to your dashboard and try creating a collection to help document your workflow, create playbooks or help with team onboarding. + +You can also import existing Markdown document by drag and dropping them to your collections + +${process.env.URL}/dashboard +`; + +export const WelcomeEmail = () => { + return ( + + +

+ Welcome to Outline! +

+ +

Outline is a place for your team to build and share knowledge.

+

+ To get started, head to your dashboard and try creating a collection + to help document your workflow, create playbooks or help with team + onboarding. +

+

+ You can also import existing Markdown document by drag and dropping + them to your collections +

+ + + +

+ +

+ + +