From dd8800c24459af688298d24b4b68e76673400830 Mon Sep 17 00:00:00 2001 From: Will McVay Date: Wed, 12 Feb 2020 11:14:29 +0000 Subject: [PATCH] fix: mail lambda custom message (#246) * fix: mail lambda custom message * fix: no-hoist in wrong place * fix: custom mailer now uses reapit-config * fix: add ga-tag to config --- .gitignore | 1 + package.json | 12 ++-- .../env.example.yml | 3 - .../cognito-custom-mail-lambda/package.json | 7 ++- .../cognito-custom-mail-lambda/serverless.yml | 6 +- .../src/mailer/__tests__/custom-mailer.ts | 29 +++++++++- .../src/mailer/custom-mailer.ts | 10 +++- .../templates/ejs/admin-user-invite.ejs | 25 ++++++++ .../templates/ejs/confirm-registration.ejs | 2 +- .../templates/ejs/forgotten-password.ejs | 9 ++- .../src/mailer/templates/ejs/index.ejs | 7 ++- .../src/mailer/templates/index.ts | 3 + .../config-manager/reapit-config.example.json | 12 ++++ scripts/release/release-serverless.js | 2 +- yarn.lock | 57 ++++++++++++++----- 15 files changed, 146 insertions(+), 39 deletions(-) delete mode 100644 packages/cognito-custom-mail-lambda/env.example.yml create mode 100644 packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/admin-user-invite.ejs diff --git a/.gitignore b/.gitignore index 515e135e3d..ec34116af9 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ elements/public out* package-lock.json .env +invite-developers.js \ No newline at end of file diff --git a/package.json b/package.json index 448590cdbd..944719aca4 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,13 @@ { "name": "root", "private": true, - "workspaces": [ - "packages/*" - ], + "workspaces": { + "packages": ["packages/*"], + "nohoist": [ + "**/cognito-custom-mail-lambda", + "**/cognito-custom-mail-lambda/**" + ] + }, "scripts": { "build": "lerna run build:prod --parallel", "fetch-config": "yarn config-manager getSecret reapit-marketplace-app-config", @@ -35,7 +39,6 @@ "amazon-cognito-identity-js": "^3.0.13", "apollo-boost": "^0.4.7", "apollo-server": "^2.9.16", - "aws-lambda": "^0.1.2", "aws-sdk": "^2.582.0", "bulma": "^0.7.5", "chart.js": "^2.9.3", @@ -43,7 +46,6 @@ "dataloader": "^2.0.0", "dayjs": "^1.8.19", "diff": "^4.0.1", - "ejs": "^3.0.1", "express": "^4.17.1", "formik": "^2.0.4", "gh-pages": "^2.2.0", diff --git a/packages/cognito-custom-mail-lambda/env.example.yml b/packages/cognito-custom-mail-lambda/env.example.yml deleted file mode 100644 index a03a6f432e..0000000000 --- a/packages/cognito-custom-mail-lambda/env.example.yml +++ /dev/null @@ -1,3 +0,0 @@ -dev: - COGNITO_USERPOOL_ID: "<>" - MARKET_PLACE_URL: "" diff --git a/packages/cognito-custom-mail-lambda/package.json b/packages/cognito-custom-mail-lambda/package.json index 126195b11d..d664c110ec 100644 --- a/packages/cognito-custom-mail-lambda/package.json +++ b/packages/cognito-custom-mail-lambda/package.json @@ -10,7 +10,7 @@ "test:ci": "cross-env TZ=UTC jest --ci --colors --coverage --silent --forceExit", "test:dev": "cross-env TZ=UTC jest --watch --verbose", "build:prod": "rimraf dist && tsc --p tsconfig.json && cp -rf ./src/mailer/templates/ejs ./dist/mailer/templates/ejs", - "release:dev": "cross-env CI=true serverless deploy --stage dev", + "release:dev": "cross-env CI=true serverless deploy --stage DEV", "release:prod": "node ../../scripts/release/release-serverless.js cognito-custom-mail-lambda", "test:update-badges": "yarn test:ci && jest-coverage-badges --input src/tests/coverage/coverage-summary.json --output src/tests/badges" }, @@ -25,6 +25,9 @@ "url": "https://github.com/reapit/foundations/issues" }, "homepage": "https://github.com/reapit/foundations#readme", - "dependencies": {}, + "dependencies": { + "aws-lambda": "^1.0.5", + "ejs": "^3.0.1" + }, "devDependencies": {} } diff --git a/packages/cognito-custom-mail-lambda/serverless.yml b/packages/cognito-custom-mail-lambda/serverless.yml index e01bfc72ca..f2918163bb 100644 --- a/packages/cognito-custom-mail-lambda/serverless.yml +++ b/packages/cognito-custom-mail-lambda/serverless.yml @@ -1,9 +1,9 @@ service: cognito-mailer -custom: ${file(./env.yml)} +custom: ${file(../../reapit-config.json)} provider: name: aws runtime: nodejs10.x - stage: ${opt:stage, 'dev'} + stage: ${opt:stage, 'DEV'} region: eu-west-2 deploymentBucket: name: cognito.mailer.${self:provider.stage} @@ -34,7 +34,7 @@ package: functions: cognitoCustomMailerHandler: - handler: public/app.cognitoCustomMailerHandler + handler: dist/app.cognitoCustomMailerHandler events: - cognitoUserPool: pool: ${self:custom.${self:provider.stage}.COGNITO_USERPOOL_ID} diff --git a/packages/cognito-custom-mail-lambda/src/mailer/__tests__/custom-mailer.ts b/packages/cognito-custom-mail-lambda/src/mailer/__tests__/custom-mailer.ts index 800e7917e5..61f8bd3ecf 100644 --- a/packages/cognito-custom-mail-lambda/src/mailer/__tests__/custom-mailer.ts +++ b/packages/cognito-custom-mail-lambda/src/mailer/__tests__/custom-mailer.ts @@ -1,6 +1,6 @@ import { customMailer } from '../custom-mailer' import { CognitoUserPoolTriggerEvent, Context } from 'aws-lambda' -import { confirmRegistrationTemplate, forgotPasswordTemplate } from '../templates/index' +import { confirmRegistrationTemplate, forgotPasswordTemplate, adminUserInviteTemplate } from '../templates/index' const context = {} as Context @@ -93,6 +93,33 @@ describe('customMailer', () => { expect(callback).toHaveBeenCalledWith(null, event) }) + it('should call the callback with an updated event if trigger source is CustomMessage_AdminCreateUser', async () => { + process.env.COGNITO_USERPOOL_ID = 'SOME_ID' + process.env.MARKET_PLACE_URL = 'SOME_URL' + const callback = jest.fn() + const event = { + triggerSource: 'CustomMessage_AdminCreateUser', + userPoolId: process.env.COGNITO_USERPOOL_ID, + response: {}, + request: { + codeParameter: 'SOME_CODE', + userAttributes: { + email: 'someone@bob.com', + }, + }, + } as Partial + + await customMailer(event as CognitoUserPoolTriggerEvent, context, callback) + expect(event.response).toEqual({ + emailSubject: 'Welcome to Reapit Foundations', + emailMessage: await adminUserInviteTemplate({ + userName: event.request?.userAttributes.email as string, + url: 'SOME_URL/developer/login', + }), + }) + expect(callback).toHaveBeenCalledWith(null, event) + }) + afterEach(() => { jest.resetAllMocks() }) diff --git a/packages/cognito-custom-mail-lambda/src/mailer/custom-mailer.ts b/packages/cognito-custom-mail-lambda/src/mailer/custom-mailer.ts index 0b3c91786c..3b31f2cdef 100644 --- a/packages/cognito-custom-mail-lambda/src/mailer/custom-mailer.ts +++ b/packages/cognito-custom-mail-lambda/src/mailer/custom-mailer.ts @@ -1,5 +1,5 @@ import { CognitoUserPoolTriggerHandler } from 'aws-lambda' -import { forgotPasswordTemplate, confirmRegistrationTemplate } from './templates/index' +import { forgotPasswordTemplate, confirmRegistrationTemplate, adminUserInviteTemplate } from './templates/index' export const customMailer: CognitoUserPoolTriggerHandler = async (event, _context, callback) => { if (event.userPoolId === process.env.COGNITO_USERPOOL_ID && event.triggerSource === 'CustomMessage_ForgotPassword') { @@ -19,5 +19,13 @@ export const customMailer: CognitoUserPoolTriggerHandler = async (event, _contex url: confirmRegistrationUrl, }) } + if (event.userPoolId === process.env.COGNITO_USERPOOL_ID && event.triggerSource === 'CustomMessage_AdminCreateUser') { + event.response.emailSubject = 'Welcome to Reapit Foundations' + const confirmRegistrationUrl = `${process.env.MARKET_PLACE_URL}/developer/login` + event.response.emailMessage = await adminUserInviteTemplate({ + userName: event.request.userAttributes.email, + url: confirmRegistrationUrl, + }) + } callback(null, event) } diff --git a/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/admin-user-invite.ejs b/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/admin-user-invite.ejs new file mode 100644 index 0000000000..d81b56545c --- /dev/null +++ b/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/admin-user-invite.ejs @@ -0,0 +1,25 @@ +
+ +

Verify your account

+
+

Hi <%= userName %>,

+
+

Welcome to Reapit Foundations.

+
+

Please see below your temporary username and password. When you click the login link, you will be re-directed to a screen where you will be asked to change your password.

+
+

User Name: {username}

+

Password: {####}

+
+
+ >LOGIN +
+
+

When you have changed your password, you will be asked to log in and will be re-directed to the developer portal.

+
+

We look forward to seeing what you build!

+
+

Best Regards,

+

Reapit Team

+
+
diff --git a/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/confirm-registration.ejs b/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/confirm-registration.ejs index 06161879a1..9f1f2bf8d9 100644 --- a/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/confirm-registration.ejs +++ b/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/confirm-registration.ejs @@ -1,4 +1,4 @@ -
+

Verify your account

diff --git a/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/forgotten-password.ejs b/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/forgotten-password.ejs index 65b6d80128..a2289a989e 100644 --- a/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/forgotten-password.ejs +++ b/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/forgotten-password.ejs @@ -1,14 +1,13 @@ -
+

Forgot Password

Hi <%= userName %>,


We have received a request to reset your Reapit Foundations password.

-

Please click the button below to continue.

- +
+

Here is your single use verification code: {####}

+

If you did not make this request, please ignore this email.


Best Regards,

diff --git a/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/index.ejs b/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/index.ejs index e946203ae9..cebb49f88e 100644 --- a/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/index.ejs +++ b/packages/cognito-custom-mail-lambda/src/mailer/templates/ejs/index.ejs @@ -14,7 +14,7 @@

Some text

Some text

- >CTA + >CTA

Some text


@@ -22,8 +22,9 @@

Reapit Team

- <%-include('forgotten-password', {userName: 'tanphamhaiduong@gmail.com', verificationCode: '123', url: 'https://dev.marketplace.reapit.com/developer/reset-password'}) %> - <%-include('confirm-registration', {userName: 'tanphamhaiduong@gmail.com', verificationCode: '123', url: 'https://dev.marketplace.reapit.com/register/confirm'}) %> + <%-include('forgotten-password', {userName: 'tanphamhaiduong@gmail.com', verificationCode: '123', url: 'https://dev.marketplace.reapit.cloud/developer/reset-password'}) %> + <%-include('confirm-registration', {userName: 'tanphamhaiduong@gmail.com', verificationCode: '123', url: 'https://dev.marketplace.reapit.cloud/register/confirm'}) %> + <%-include('admin-user-invite', {userName: 'tanphamhaiduong@gmail.com', verificationCode: '123'}, 'https://dev.marketplace.reapit.cloud/developer/login') %> diff --git a/packages/cognito-custom-mail-lambda/src/mailer/templates/index.ts b/packages/cognito-custom-mail-lambda/src/mailer/templates/index.ts index aabc430161..ec0b97125d 100644 --- a/packages/cognito-custom-mail-lambda/src/mailer/templates/index.ts +++ b/packages/cognito-custom-mail-lambda/src/mailer/templates/index.ts @@ -6,3 +6,6 @@ export const forgotPasswordTemplate = async (data: ForgottenPasswordTemplatePara export const confirmRegistrationTemplate = async (data: ConfirmPasswordTemplateParams) => ejs.renderFile(`${__dirname}/ejs/confirm-registration.ejs`, data) + +export const adminUserInviteTemplate = async (data: ConfirmPasswordTemplateParams) => + ejs.renderFile(`${__dirname}/ejs/admin-user-invite.ejs`, data) diff --git a/packages/config-manager/reapit-config.example.json b/packages/config-manager/reapit-config.example.json index 491c3e5741..0524de3606 100644 --- a/packages/config-manager/reapit-config.example.json +++ b/packages/config-manager/reapit-config.example.json @@ -1,8 +1,11 @@ { "LOCAL": { + "REAPIT_ENV": "", "PLATFORM_BASE_URL": "", "MARKETPLACE_BASE_URL": "", + "MARKET_PLACE_URL": "", "MARKETPLACE_API_KEY": "", + "MARKETPLACE_GOOGLE_ANALYTICS_KEY": "", "NODE_ENV": "", "NPM_TOKEN": "", "GOOGLE_MAPS_API_KEY": "", @@ -30,9 +33,12 @@ "SENTRY_PROJECT_URL_LTL_APP": "" }, "DEV": { + "REAPIT_ENV": "", "PLATFORM_BASE_URL": "", "MARKETPLACE_BASE_URL": "", + "MARKET_PLACE_URL": "", "MARKETPLACE_API_KEY": "", + "MARKETPLACE_GOOGLE_ANALYTICS_KEY": "", "NODE_ENV": "", "NPM_TOKEN": "", "GOOGLE_MAPS_API_KEY": "", @@ -60,9 +66,12 @@ "SENTRY_PROJECT_URL_LTL_APP": "" }, "PROD": { + "REAPIT_ENV": "", "PLATFORM_BASE_URL": "", "MARKETPLACE_BASE_URL": "", + "MARKET_PLACE_URL": "", "MARKETPLACE_API_KEY": "", + "MARKETPLACE_GOOGLE_ANALYTICS_KEY": "", "NODE_ENV": "", "NPM_TOKEN": "", "GOOGLE_MAPS_API_KEY": "", @@ -90,9 +99,12 @@ "SENTRY_PROJECT_URL_LTL_APP": "" }, "DEMO": { + "REAPIT_ENV": "", "PLATFORM_BASE_URL": "", "MARKETPLACE_BASE_URL": "", + "MARKET_PLACE_URL": "", "MARKETPLACE_API_KEY": "", + "MARKETPLACE_GOOGLE_ANALYTICS_KEY": "", "NODE_ENV": "", "NPM_TOKEN": "", "GOOGLE_MAPS_API_KEY": "", diff --git a/scripts/release/release-serverless.js b/scripts/release/release-serverless.js index 6c808a6b89..43a6167f95 100644 --- a/scripts/release/release-serverless.js +++ b/scripts/release/release-serverless.js @@ -12,7 +12,7 @@ const releaseServerless = async () => { } if (packageName === packageNameOnTag) { - execSync('cross-env CI=true serverless deploy --stage prod') + execSync('cross-env CI=true serverless deploy --stage PROD') const previousTag = getPreviousTag({ packageName: packageNameOnTag }) await editReleaseNote({ packageName: packageNameOnTag, version, previousTag }) diff --git a/yarn.lock b/yarn.lock index 329ced1b5f..b7319dc6b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5630,16 +5630,32 @@ awesome-typescript-loader@^5.2.1: source-map-support "^0.5.3" webpack-log "^1.2.0" -aws-lambda@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-0.1.2.tgz#19b1585075df31679597b976a5f1def61f12ccee" - integrity sha1-GbFYUHXfMWeVl7l2pfHe9h8SzO4= +aws-lambda@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/aws-lambda/-/aws-lambda-1.0.5.tgz#9f40ca36da2aca8345230d6252c6e0da5a772dcf" + integrity sha512-rRBZT5mitbeb/qdqHrFiymFQ8k+uc8WlN2Y16OhsCEZzYHKRqFzRirO7gIozDohNuu7T27S6w88KBFpI0cS1NQ== dependencies: - aws-sdk "^*" - commander "^2.5.0" - dotenv "^0.4.0" + aws-sdk "*" + commander "^3.0.2" + js-yaml "^3.13.1" + watchpack "^2.0.0-beta.10" -aws-sdk@^*, aws-sdk@^2.582.0: +aws-sdk@*: + version "2.615.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.615.0.tgz#36233df3ae603ad38cc4181e8d92c7d6e5dae16c" + integrity sha512-ktkOQgJLTcsfLzy/GPfUiEJd09SeJPnUj7ZeXa0Wb2/JVIRDbSmyG/IYQqAvXWUcD4thuv2h9wbLgXyzvX8dtw== + dependencies: + buffer "4.9.1" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.3.2" + xml2js "0.4.19" + +aws-sdk@^2.582.0: version "2.612.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.612.0.tgz#3af06638ec785bad10986b81ce265422fca552e3" integrity sha512-/oAeVw9okULGczQLNMAO3/w9sA2ubf/+iqRQRXRjrJXVUi7INV6qYnNzIXzy7GabOkN7xpZiTbVcU+Yij5yrxg== @@ -7537,11 +7553,16 @@ commander@2.17.x: resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== -commander@^2.11.0, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.5.0, commander@^2.9.0, commander@~2.20.3: +commander@^2.11.0, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.9.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" + integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== + commander@^4.0.0, commander@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" @@ -8964,11 +8985,6 @@ dotenv-webpack@^1.7.0: dependencies: dotenv-defaults "^1.0.2" -dotenv@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-0.4.0.tgz#f6fb351363c2d92207245c737802c9ab5ae1495a" - integrity sha1-9vs1E2PC2SIHJFxzeALJq1rhSVo= - dotenv@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.2.0.tgz#941c0410535d942c8becf28d3f357dbd9d476064" @@ -11095,6 +11111,11 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@~7.1.1: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -22851,6 +22872,14 @@ watchpack@^1.6.0: graceful-fs "^4.1.2" neo-async "^2.5.0" +watchpack@^2.0.0-beta.10: + version "2.0.0-beta.12" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.0.0-beta.12.tgz#bed6878b020c8f43f5b88b7031dfb2b2092755f5" + integrity sha512-vUJN6XQCBqrUkyX74WNopUvASMLqgicYGA5nO/FwSfdmLQgrfy44Z+Jl2YHHHXy/gDO6RlbArR26YQGeIWfoAg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df"