Skip to content

Instantly share code, notes, and snippets.

@Sparticuz
Created July 21, 2023 18:47
Show Gist options
  • Save Sparticuz/adef97c2ed12cb6d83aa6122f629b4e9 to your computer and use it in GitHub Desktop.
Save Sparticuz/adef97c2ed12cb6d83aa6122f629b4e9 to your computer and use it in GitHub Desktop.
encrypt-pdf
/* eslint-disable no-await-in-loop */
import { writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import type { Readable } from "node:stream";
import { encrypt, type EncryptOptions } from "node-qpdf2";
import { getFileFromS3, parseS3Uri, uploadFilePathToS3 } from "./aws.s3.js";
import notify from "./aws.sqs.js";
import { guid } from "./guid.js";
/** Writes a Readable to a File in tmpdir() */
export const writeTemporaryFile = async (file: Readable): Promise<string> => {
const filePath = join(tmpdir(), `${guid()}.pdf`);
// eslint-disable-next-line security/detect-non-literal-fs-filename
await writeFile(filePath, file);
return filePath;
};
/** Returns the local encrypted file path */
export const encryptFile = async (
input: string,
userPassword = "1234",
): Promise<string> => {
const options: EncryptOptions = {
input,
output: join(tmpdir(), `${guid()}.pdf`),
password: userPassword,
};
await encrypt(options);
return options.output as string;
};
/* c8 ignore start */
export default async (event: AWSLambda.SQSEvent) => {
const allPromises = [];
// First, let's loop through the sqs events
for (const record of event.Records) {
// Get the body of the record
const json = JSON.parse(record.body);
const payloads =
// @ts-expect-error I want to iterate
typeof json[Symbol.iterator] === "function"
? (json)
: ([json]);
// For each payload in the json body
for (const payload of payloads) {
/** The URI of the file to encrypt */
let filePath = payload.encrypt.url;
// If there is a password specified, encrypt the file
if (payload.encrypt.password) {
// Parse the s3 uri in order to get the bucket and file
const { bucket, key } = parseS3Uri(payload.encrypt.url);
/** The unencrypted Readable PDF stream */
const unencryptedFile = getFileFromS3(bucket as string, key as string);
/** The location of the unencrypted pdf file. */
const unencryptedTemporaryFilePath = writeTemporaryFile(
await unencryptedFile,
);
/** The local encrypted pdf file path */
const encryptedFilePath = encryptFile(
await unencryptedTemporaryFilePath,
payload.encrypt.password,
);
/** The encrypted pdf URI in S3 */
const encryptedURI = uploadFilePathToS3(await encryptedFilePath, false);
filePath = await encryptedURI;
}
// Send an email to the FO
allPromises.push(sendEmailFunction(payload, filePath));
}
}
await Promise.all(allPromises);
};
/* c8 ignore end */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment