Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PIDM-205] feat(pdf): remove pdf generation and dependencies #92

Merged
merged 1 commit into from
Feb 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ RUN yarn build
FROM node:18.13.0-alpine AS production
WORKDIR /app
RUN apk add --no-cache nss freetype harfbuzz ca-certificates udev chromium
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
COPY --from=builder ./app/dist ./dist
COPY package* ./
COPY tsconfig* ./
Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,8 @@
"io-ts-from-json-schema": "^0.0.21",
"io-ts-reporters": "^2.0.1",
"jest-handlebars": "^1.0.0",
"jest-puppeteer": "^6.1.1",
"node-forge": "^1.3.1",
"nodemailer": "^6.7.7",
"puppeteer": "^15.4.0",
"winston": "^3.8.1"
}
}
17 changes: 2 additions & 15 deletions src/__tests__/RetryQueueListener.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { SentMessageInfo } from "nodemailer/lib/ses-transport";
import { Transporter } from "nodemailer";
import { addRetryQueueListener } from "../queues/RetryQueueListener";
import { QueueReceiveMessageResponse } from "@azure/storage-queue";
import * as puppeteer from "puppeteer";
import registerHelpers from "handlebars-helpers";
import { mockReq } from "../__mocks__/data_mock";

Expand Down Expand Up @@ -57,11 +56,6 @@ describe("retry queue", () => {

jest.spyOn(global, 'setInterval');

const browser = await puppeteer.launch({
args: ["--no-sandbox"],
headless: true
});

retryQueueClient.createIfNotExists = jest.fn().mockResolvedValue({});

const mockedMailFunction = jest.fn().mockResolvedValueOnce(sentMessageMock(1)).mockResolvedValueOnce(sentMessageMock(3)).mockResolvedValueOnce(sentMessageMock(3));
Expand Down Expand Up @@ -93,7 +87,7 @@ describe("retry queue", () => {
retryQueueClient.createIfNotExists();
const spyDecrypt = jest.spyOn(apiPdvClient, 'findPiiUsingGET').mockResolvedValue({_tag: "Right", right:{ status:200 , value: {pii: JSON.stringify(requestMock.body)}, headers: "" as any} });

addRetryQueueListener(config,mailTrasporterMock,browser);
addRetryQueueListener(config,mailTrasporterMock);

expect(setInterval).toHaveBeenCalledTimes(1);
expect(setInterval).toHaveBeenLastCalledWith(expect.any(Function), 1000);
Expand All @@ -102,7 +96,6 @@ describe("retry queue", () => {

console.log(mockedMailFunction.mock.calls.length);

await browser?.close();
jest.useRealTimers();
});

Expand All @@ -113,11 +106,6 @@ describe("retry queue", () => {

jest.spyOn(global, 'setInterval');

const browser = await puppeteer.launch({
args: ["--no-sandbox"],
headless: true
});

retryQueueClient.createIfNotExists = jest.fn().mockResolvedValue({});

const mockReceiveMessages = jest.fn().mockResolvedValueOnce({receivedMessageItems:
Expand All @@ -138,15 +126,14 @@ describe("retry queue", () => {
retryQueueClient.createIfNotExists();
const spyDecrypt = jest.spyOn(apiPdvClient, 'findPiiUsingGET').mockResolvedValue({_tag: "Right", right:{ status: 400 , value: { status: 400, title: ""}, headers: "" as any} });

addRetryQueueListener(config, mailTrasporterMock, browser);
addRetryQueueListener(config, mailTrasporterMock);

expect(setInterval).toHaveBeenCalledTimes(1);
expect(setInterval).toHaveBeenLastCalledWith(expect.any(Function), 1000);
jest.advanceTimersByTime(1000);

expect(mockReceiveMessages).toHaveBeenCalledTimes(1);

await browser?.close();
jest.useRealTimers();
});
});
14 changes: 2 additions & 12 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Logger } from "winston";
import { toExpressHandler } from "@pagopa/ts-commons/lib/express";
import * as bodyParser from "body-parser";
import * as nodemailer from "nodemailer";
import * as puppeteer from "puppeteer";
import { Transporter } from "nodemailer";
import registerHelpers from "handlebars-helpers";
import { SendRawEmailCommand, SES } from "@aws-sdk/client-ses";
Expand All @@ -29,10 +28,6 @@ export const startApp = async (
`⚡️⚡️⚡️⚡️⚡️ pagopa-notification-service server Starting at https://localhost:${config.PORT} ⚡️⚡️⚡️⚡️⚡️`
);

logger.info(
`⚡️⚡️⚡️⚡️⚡️ pagopa-notification-service server setup puppeter for pdf generator⚡️⚡️⚡️⚡️⚡️`
);

logger.info(
`⚡️⚡️⚡️⚡️⚡️ pagopa-notification-service server setup AWS mail mailTrasporter ⚡️⚡️⚡️⚡️⚡️`
);
Expand Down Expand Up @@ -63,13 +58,8 @@ export const startApp = async (

const jsonParser = bodyParser.json();

const browserEngine = await puppeteer.launch({
args: ["--no-sandbox"],
headless: true
});

const sendMailtHandler = toExpressHandler(
EmailsControllers.sendMail(config, mailTrasporter, browserEngine)
EmailsControllers.sendMail(config, mailTrasporter)
);
const getInfoHandler = toExpressHandler(infoController(config, logger));

Expand All @@ -88,7 +78,7 @@ export const startApp = async (
);
server.listen(config.PORT);

addRetryQueueListener(config, mailTrasporter, browserEngine);
addRetryQueueListener(config, mailTrasporter);

logger.info(
`⚡️⚡️⚡️⚡️⚡️ pagopa-notification-service Server started at https://localhost:${config.PORT} ⚡️⚡️⚡️⚡️⚡️`
Expand Down
72 changes: 11 additions & 61 deletions src/controllers/EmailsControllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import * as E from "fp-ts/lib/Either";
import * as TE from "fp-ts/lib/TaskEither";
import { pipe } from "fp-ts/lib/function";
import * as t from "io-ts";
import { Browser } from "puppeteer";
import { Envelope } from "nodemailer/lib/mime-node";
import { formatValidationErrors } from "io-ts-reporters";
import { AsControllerFunction, AsControllerResponseType } from "../util/types";
Expand All @@ -49,33 +48,16 @@ const sendEmailWithAWS = async (
subject: string,
htmlData: string,
textData: string,
mailTrasporter: Transporter<SESTransport.SentMessageInfo>,
_pdfData: O.Option<Promise<Buffer>>,
_pdfName: string
mailTrasporter: Transporter<SESTransport.SentMessageInfo>
// eslint-disable-next-line max-params
) => {
/*
logger.info("Attachment configurations...");
const attachments = await Promise.all(
pipe(
pdfData,
O.map(async content => ({
filename: pdfName,
content: await content,
contentType: "application/pdf"
})),
A.fromOption
)
);
*/
const messageInfoOk: SESTransport.SentMessageInfo = await mailTrasporter.sendMail(
{
from: senderEmail,
to: recipientEmail,
subject,
html: htmlData,
text: textData
// attachments
}
);
logger.info(`Message sent with ID ${messageInfoOk.messageId}`);
Expand Down Expand Up @@ -126,7 +108,6 @@ export const sendEmail = async (
schema: {
readonly default: t.Type<unknown>;
},
browserEngine: Browser,
mailTrasporter: Transporter<SESTransport.SentMessageInfo>,
config: IConfig,
retryCount: number
Expand All @@ -149,15 +130,6 @@ export const sendEmail = async (
.toString();
const htmlTemplate = Handlebars.compile(htmlTemplateRaw);

const pathExists = O.fromPredicate((path: string) => fs.existsSync(path));

const pdfTemplate = pipe(
pathExists(
`dist/src/templates/${templateId}/${templateId}.template.pdf.html`
),
O.map(path => fs.readFileSync(path).toString()),
O.map(Handlebars.compile)
);
// add pagopa logo URI taken from configuration
const enrichedParameters = {
...params.body.parameters,
Expand All @@ -169,30 +141,14 @@ export const sendEmail = async (
return pipe(
enrichedParameters,
schema.default.decode,
E.map<unknown, readonly [string, string, O.Option<string>]>(
(templateParams: unknown) => [
htmlTemplate(templateParams),
textTemplate(templateParams),
pipe(
pdfTemplate,
O.map(pdf => pdf(templateParams))
)
]
),
E.map<unknown, readonly [string, string]>((templateParams: unknown) => [
htmlTemplate(templateParams),
textTemplate(templateParams)
]),
E.map(
async ([htmlMarkup, textMarkup, pdfMarkup]): Promise<
async ([htmlMarkup, textMarkup]): Promise<
O.Option<SESTransport.SentMessageInfo>
> => {
const pdfData = pipe(
pdfMarkup,
O.map(async markup => {
const page = await browserEngine.newPage();
await page.setContent(markup);

return await page.pdf({ printBackground: true });
}),
O.map(async v => await v)
);
logger.info(
`[${clientId}] - Sending email with template ${templateId}`
);
Expand All @@ -212,9 +168,7 @@ export const sendEmail = async (
params.body.subject,
htmlMarkup,
textMarkup,
mailTrasporter,
pdfData,
"test.pdf"
mailTrasporter
)
);
} catch (error) {
Expand Down Expand Up @@ -275,12 +229,10 @@ export const sendEmail = async (

export const sendMailController: (
config: IConfig,
mailTrasporter: Transporter<SESTransport.SentMessageInfo>,
browserEngine: Browser
mailTrasporter: Transporter<SESTransport.SentMessageInfo>
) => AsControllerFunction<SendNotificationEmailT> = (
config,
mailTrasporter,
browserEngine
mailTrasporter
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
) => async params => {
const templateId = params.body.templateId;
Expand All @@ -290,7 +242,6 @@ export const sendMailController: (
return sendEmail(
params,
schema,
browserEngine,
mailTrasporter,
config,
config.MAX_RETRY_ATTEMPTS
Expand Down Expand Up @@ -336,14 +287,13 @@ const headerValidationErrorHandler: (
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
export function sendMail(
config: IConfig,
mailTrasporter: Transporter<SESTransport.SentMessageInfo>,
browserEngine: Browser
mailTrasporter: Transporter<SESTransport.SentMessageInfo>
): (
req: express.Request
) => Promise<
AsControllerResponseType<TypeofApiResponse<SendNotificationEmailT>>
> {
const controller = sendMailController(config, mailTrasporter, browserEngine);
const controller = sendMailController(config, mailTrasporter);
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
return async req =>
pipe(
Expand Down
Loading
Loading