This small demo project shows a way to generate PDFs from mustache HTML templates using puppeteer and mustache.js.
Puppeteer is an open-source Node.js library providing control to Chrome or Chromium used for automated testing and creating PDFs from HTML. Puppeteer is maintained by the Chrome DevTools team.
https://pptr.dev
https://github.com/puppeteer/puppeteer
An open-source JavaScript library to render mustache templates. The mustache template syntax supports variables, conditional templates, repeatable sections and inclusion of other templates. The mustache template engine is widely available.
https://github.com/janl/mustache.js
Some remarks concerning security:
- Ensure user input is validated.
- Ensure the npm packages and docker image are up to date.
- Only allow access from trusted services. This is often achieved using json web tokens. Thanks to the package jsonwebtoken this was easily implemented in template-renderer.js.
- For serving over https see https://expressjs.com/en/5x/api.html#app.listen and https://nodejs.org/api/https.html#httpscreateserveroptions-requestlistener.
See package.json for scripts to run, build and test template-renderer.js. It provides scripts to build some example templates as well.
- Run
npm run generate-keys jwt
to create a private and public key. The public key is used by template-renderer.js for validating JWT's. - Run
npm run start:test
to serve template-renderer.js on port 5000 and a HTML test page on port 5021. The examples directory contains templates which can be used for testing. - Run
npm run start:image
to serve template-renderer.js on port 5000 and runstart:test-page
to run a HTML test page on port 5021. The examples directory contains templates which can be used for testing. - Run
npx prettier . --check
ornpx prettier . --write
to format code using prettier (an opinionated formatter).
A Dockerfile is included in this repository. See https://pptr.dev/guides/docker and https://github.com/puppeteer/puppeteer/blob/main/docker/Dockerfile for more information.
- template-renderer.js - Combines Puppeteer and mustache.js with a few lines of code in order to create PDFs from mustache HTML templates.
The service waits untilwindow.readyForPdf != false
. This way the template can run JavaScript before it's rendered. - generate-keys.js - Generates a private and public key.
- test-page.js - Serves a test page for testing template-renderer.js.
The package jwks-rsa provides functionality for validating JWT's created with a public key from a JSON Web Key Set (JWKS).
For an example install the package with npm i jwks-rsa
and adjust the code as written below.
// add
const jwksClient = require("jwks-rsa");
// change validateToken
const validateToken = createTokenValidationFunction(
"https://some-url...",
"template",
);
// replace createTokenValidationFunction with the following function
function createTokenValidationFunction(url, requiredScope) {
return (token) => {
var client = jwksClient({ jwksUri: url });
function getKey(header, callback) {
client.getSigningKey(header.kid, function (err, key) {
if (err) {
logger.error({ message: err.message });
}
var signingKey = key?.publicKey || key?.rsaPublicKey;
callback(null, signingKey);
});
}
return verifyToken(token, getKey, requiredScope);
};
}
For local testing - Extra self-signed certificate(s) can be provided with a node environment variable: NODE_EXTRA_CA_CERTS.