Skip to content

Commit

Permalink
fix: integration test (#148)
Browse files Browse the repository at this point in the history
* chore: npm-audit (#140)

* chore: fix tests

* chore: uuid upgrade; package fix up

* chore: nodemailer update

* chore: middy upgrade

* chore: fix uuid test

* chore: lint fixes and rules

* fix: middy import (#141)

* chore: update example env var value

* chore: mock verify for storage integration

* chore: use esm export

* chore: add env var for local e2e test

* chore: use serverless-dotenv-plugin in email

* chore: refactor test name to sepolia

* chore: remove unused rules

* chore: remove unused assertion

---------

Co-authored-by: Yan <15334762+yanlow@users.noreply.github.com>
  • Loading branch information
zixiang2018 and yanlow committed Jan 12, 2024
1 parent 2cdf088 commit f951b97
Show file tree
Hide file tree
Showing 25 changed files with 12,798 additions and 14,512 deletions.
7 changes: 5 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ RECAPTCHA_SECRET=<INSERT_KEY>
NETWORK=sepolia
EMAIL_API_KEYS=KEY1:KEY2
EMAIL_INTEGRATION_TEST_API_KEY=KEY
BUCKET_NAME=opencerts-functions-transfer-document-storage
BUCKET_NAME=oc-functions-storage-stg
OBJECT_TTL=31
DISABLE_DOMAIN=false
ENABLE_STORAGE_UPLOAD_API_KEY=false
ENABLE_STORAGE_UPLOAD_API_KEY=false
EMAIL_ENDPOINT=http://localhost:3000/stg
VERIFY_ENDPOINT=http://localhost:4000/stg
STORAGE_ENDPOINT=http://localhost:5000/stg
5 changes: 4 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
"argsIgnorePattern": "^_"
}
],
"prefer-regex-literals": "off",
"func-names": ["error", "as-needed"],
"prettier/prettier": "error",
"no-unused-expressions": "off"
"no-unused-expressions": "off",
"import/prefer-default-export": "off"

}
}
6 changes: 4 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module.exports = {
transform: {
"\\.html": "jest-raw-loader",
"\\.txt": "jest-raw-loader",
"\\.subject": "jest-raw-loader"
}
"\\.subject": "jest-raw-loader",
"\\.m?jsx?$": "jest-esm-transformer"
},
transformIgnorePatterns: ["node_modules/(?!(axios)/)"]
};
27,008 changes: 12,649 additions & 14,359 deletions package-lock.json

Large diffs are not rendered by default.

43 changes: 24 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,40 +31,45 @@
"license": "ISC",
"dependencies": {
"@govtechsg/oa-encryption": "^1.3.5",
"@govtechsg/open-attestation": "^6.6.0",
"@govtechsg/open-attestation": "^6.9.0",
"@govtechsg/opencerts-verify": "^3.1.3",
"aws-sdk": "^2.590.0",
"@middy/core": "^5.1.0",
"@middy/http-cors": "^5.1.0",
"aws-sdk": "^2.1523.0",
"lodash": "^4.17.13",
"middy": "^0.36.0",
"node-fetch": "^2.6.1",
"nodemailer": "^4.6.8",
"serverless": "^3.32.2",
"nodemailer": "^6.9.7",
"serverless": "^3.38.0",
"serverless-http": "^3.2.0",
"uuid": "^3.3.2"
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/jest": "^29.5.2",
"@types/jest": "^29.5.11",
"copy-webpack-plugin": "^5.1.1",
"dotenv": "^7.0.0",
"eslint": "^5.16.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-config-prettier": "^3.0.1",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-jest": "^22.21.0",
"eslint-plugin-prettier": "^2.6.2",
"eslint": "^8.56.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jest": "^27.6.0",
"eslint-plugin-prettier": "^5.1.0",
"file-loader": "^6.0.0",
"jest": "^24.7.1",
"jest": "^27.5.1",
"jest-esm-transformer": "^1.0.0",
"jest-raw-loader": "^1.0.1",
"npm-run-all": "^4.1.5",
"prettier": "^1.19.1",
"prettier": "^3.1.1",
"raw-loader": "^4.0.1",
"serverless-domain-manager": "^3.3.2",
"serverless-domain-manager": "^7.3.3",
"serverless-dotenv-plugin": "^6.0.0",
"serverless-offline": "^12.0.4",
"serverless-s3-local": "^0.5.4",
"serverless-offline": "^13.3.2",
"serverless-s3-local": "^0.8.1",
"serverless-s3-remover": "^0.6.0",
"serverless-webpack": "^5.11.0",
"serverless-webpack": "^5.13.0",
"supertest": "^4.0.2",
"webpack": "^5.86.0"
},
"prettier": {
"trailingComma": "none"
}
}
21 changes: 10 additions & 11 deletions src/email/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const middy = require("middy");
import middy from "@middy/core";
import cors from "@middy/http-cors";

const { get } = require("lodash");
const { cors } = require("middy/middlewares");
const { isValid, verify } = require("@govtechsg/opencerts-verify");

const recaptcha = require("./recaptcha");
Expand All @@ -9,15 +10,15 @@ const config = require("./config");

const captchaValidator = recaptcha(config.recaptchaSecret);

const validateApiKey = key => {
const validateApiKey = (key) => {
if (!key) return false;
if (config.emailApiKeys.includes(key)) {
return true;
}
throw new Error("Invalid API key");
};

const handleEmail = async (event, _context, callback) => {
const handleEmail = async (event) => {
try {
const { to, data, captcha } = JSON.parse(event.body);

Expand All @@ -38,18 +39,16 @@ const handleEmail = async (event, _context, callback) => {
// Send certificate out
await certificateMailer({ to, certificate: data });

callback(null, {
return {
statusCode: 200,
body: JSON.stringify({ success: true })
});
};
} catch (e) {
callback(null, {
return {
statusCode: 400,
body: JSON.stringify({ error: e.message })
});
};
}
};

const handler = middy(handleEmail).use(cors());

module.exports = { handler };
export const handler = middy().use(cors()).handler(handleEmail);
78 changes: 38 additions & 40 deletions src/email/mailer/mailer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,47 +15,45 @@ const sendRawMail = (transporter, data) =>

// prefix is shitty and used only by the tests, I'm tired by this and dont want to find for another way to handle this
// enjoy yourself
const sendCertificate = transporter => async ({
to,
certificate,
prefix = ""
}) => {
const { html, text, subject } = messageTemplate(certificate);
const content = JSON.stringify(certificate);
const sendCertificate =
(transporter) =>
async ({ to, certificate, prefix = "" }) => {
const { html, text, subject } = messageTemplate(certificate);
const content = JSON.stringify(certificate);

// eslint-disable-next-line no-console
console.log("Email:", to);
// eslint-disable-next-line no-console
console.log("Certificate:", content);
// eslint-disable-next-line no-console
console.log("Email:", to);
// eslint-disable-next-line no-console
console.log("Certificate:", content);

return sendRawMail(transporter, {
to,
from: FROM_ADDRESS,
subject,
html,
text,
attachments: [
{
filename: "logo.png",
path: `${prefix}static/logo.png`,
cid: "logo"
},
{
filename: "certificate.png",
path: `${prefix}static/certificate.png`,
cid: "certificate"
},
{
filename: "dropzone.png",
path: `${prefix}static/dropzone.png`,
cid: "dropzone"
},
{
filename: FILE_NAME,
content
}
]
});
};
return sendRawMail(transporter, {
to,
from: FROM_ADDRESS,
subject,
html,
text,
attachments: [
{
filename: "logo.png",
path: `${prefix}static/logo.png`,
cid: "logo"
},
{
filename: "certificate.png",
path: `${prefix}static/certificate.png`,
cid: "certificate"
},
{
filename: "dropzone.png",
path: `${prefix}static/dropzone.png`,
cid: "dropzone"
},
{
filename: FILE_NAME,
content
}
]
});
};

module.exports = sendCertificate;
2 changes: 1 addition & 1 deletion src/email/mailer/mailer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const etherealCreateAccount = () =>
});

const validateRawEmail = async ({ url, subject, text, html, to }) => {
const rawEmail = await fetch(url).then(res => res.text());
const rawEmail = await fetch(url).then((res) => res.text());
return (
rawEmail.includes(subject) &&
rawEmail.includes(`To: ${to}`) &&
Expand Down
2 changes: 1 addition & 1 deletion src/email/messageTemplate/messageTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const htmlMailTemplate = template(htmlMailTemplateContent);
const txtMailTemplate = template(txtMailTemplateContent);
const subjectMailTemplate = template(subjectMailTemplateContent);

const messageTemplate = certificate => {
const messageTemplate = (certificate) => {
try {
// Might throw if the certificate is undefined
const data = openAttestation.getData(certificate);
Expand Down
2 changes: 1 addition & 1 deletion src/email/messageTemplate/messageTemplate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const expectedContentSubject = fs.readFileSync(expectedPathSubject).toString();

describe("messageTemplate", () => {
it("returns html and text given a certificate", () => {
const extractContent = str => str.replace(/ +/g, "");
const extractContent = (str) => str.replace(/ +/g, "");
const message = messageTemplate(certificate);
expect(extractContent(message.html)).toEqual(
extractContent(expectedContentHtml)
Expand Down
6 changes: 3 additions & 3 deletions src/email/recaptcha/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const fetch = require("node-fetch").default;
const { URLSearchParams } = require("url");

const recaptcha = secret => async response => {
const recaptcha = (secret) => async (response) => {
const params = new URLSearchParams();
params.append("secret", secret);
params.append("response", response);
return fetch("https://www.google.com/recaptcha/api/siteverify", {
method: "POST",
body: params
})
.then(res => res.json())
.then(res => res.success);
.then((res) => res.json())
.then((res) => res.success);
};

module.exports = recaptcha;
1 change: 1 addition & 0 deletions src/email/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ custom:
includeModules:
packagePath: "../../package.json"
plugins:
- serverless-dotenv-plugin
- serverless-offline
- serverless-domain-manager
- serverless-webpack
13 changes: 5 additions & 8 deletions src/storage/create.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
const middy = require("middy");
const { cors } = require("middy/middlewares");
import middy from "@middy/core";
import cors from "@middy/http-cors";

const { uploadDocument } = require("./documentService");

const handleCreate = async event => {
const handleCreate = async (event) => {
try {
const { document, ttl } = JSON.parse(event.body);
const receipt = await uploadDocument(document, ttl);
Expand All @@ -27,8 +28,4 @@ const handleCreate = async event => {
}
};

const handler = middy(handleCreate).use(cors());

module.exports = {
handler
};
export const handler = middy().use(cors()).handler(handleCreate);
13 changes: 5 additions & 8 deletions src/storage/createAtId.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
const middy = require("middy");
const { cors } = require("middy/middlewares");
import middy from "@middy/core";
import cors from "@middy/http-cors";

const { uploadDocumentAtId } = require("./documentService");

const handleCreateAtId = async event => {
const handleCreateAtId = async (event) => {
try {
const { document, ttl } = JSON.parse(event.body);
const { id } = event.pathParameters;
Expand Down Expand Up @@ -30,8 +31,4 @@ const handleCreateAtId = async event => {
}
};

const handler = middy(handleCreateAtId).use(cors());

module.exports = {
handler
};
export const handler = middy().use(cors()).handler(handleCreateAtId);
10 changes: 5 additions & 5 deletions src/storage/documentService/documentService.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const uuid = require("uuid/v4");
const { v4: uuidv4 } = require("uuid");
const { verify, isValid } = require("@govtechsg/opencerts-verify");
const {
encryptString,
Expand Down Expand Up @@ -40,7 +40,7 @@ const getDocument = async (id, { cleanup } = { cleanup: false }) => {
return document;
};

const getDecryptionKey = async id => {
const getDecryptionKey = async (id) => {
const params = {
Bucket: config.bucketName,
Key: id
Expand All @@ -50,7 +50,7 @@ const getDecryptionKey = async id => {
return document;
};

const calculateExpiryTimestamp = ttlInMicroseconds =>
const calculateExpiryTimestamp = (ttlInMicroseconds) =>
Date.now() + ttlInMicroseconds;

const uploadDocumentAtId = async (
Expand Down Expand Up @@ -122,7 +122,7 @@ const uploadDocument = async (
type,
ttl
},
uuid()
uuidv4()
);
return {
id,
Expand All @@ -134,7 +134,7 @@ const uploadDocument = async (

const getQueueNumber = async () => {
const created = Math.floor(Date.now() / 1000);
const id = uuid();
const id = uuidv4();
const tempData = {
id,
key: generateEncryptionKey(),
Expand Down
2 changes: 1 addition & 1 deletion src/storage/dynamoDb/dynamoDb.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const get = (...args) =>
dynamoClient
.get(...args)
.promise()
.then(results => {
.then((results) => {
if (results.Item) {
return results.Item;
}
Expand Down
Loading

0 comments on commit f951b97

Please sign in to comment.