Skip to content

Commit

Permalink
Testing in placeholder-pdfkit010
Browse files Browse the repository at this point in the history
  • Loading branch information
vbuch committed Oct 4, 2023
1 parent 8b92600 commit d6b4629
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 94 deletions.
1 change: 0 additions & 1 deletion jest.config.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ module.exports = {
],
coveragePathIgnorePatterns: [
'/node_modules/',
'/src/helpers/pdfkit/',
],
coverageThreshold: {
global: {
Expand Down
66 changes: 66 additions & 0 deletions packages/internal-utils/createPdfkitDocument.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
var PDFDocument = require('pdfkit');

/**
* @typedef {object} ReturnType
* @prop {Promise<Buffer>} promise
* @prop {PDFDocument} pdf
*/

/**
* Creates a Buffer containing a PDF.
* Returns a Promise that is resolved with the resulting Buffer of the PDFDocument.
* @returns {ReturnType}
*/
module.exports = function (params) {
var requestParams = {
placeholder: {
contactInfo: '[email protected]',
name: 'test name',
location: 'test Location',
},
text: 'node-signpdf',
pages: 1,
layout: 'portrait',
end: true,
};
Object.assign(requestParams, params);
if (requestParams.pages < 1) {
requestParams.pages = 1;
}

var pdf = new PDFDocument({
autoFirstPage: false,
size: 'A4',
layout: requestParams.layout,
bufferPages: true,
});;
pdf.info.CreationDate = '';

// Add some content to the page(s)
for (var i = 0; i < requestParams.pages; i += 1) {
pdf
.addPage()
.fillColor('#333')
.fontSize(25)
.moveDown()
.text(requestParams.text)
.save();
}

var ended = new Promise(function (resolve) {
// Collect the ouput PDF
// and, when done, resolve with it stored in a Buffer
var pdfChunks = [];
pdf.on('data', function (data) {
pdfChunks.push(data);
});
pdf.on('end', function () {
resolve(Buffer.concat(pdfChunks));
});
})

return {
ended: ended,
pdf: pdf,
}
};
11 changes: 4 additions & 7 deletions packages/internal-utils/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
var fs = require('fs');
var readTestResource = require('./readTestResource');
var createPdfkitDocument = require('./createPdfkitDocument');

module.exports = {
readTestResource: function (filename) {
if (filename === '.' || (/(\/|\\|\.\.)/).test(filename)) {
throw new Error(`"${filename}" is invalid filename.`);
}
return fs.readFileSync(`${__dirname}/../../resources/${filename}`);
}
readTestResource: readTestResource,
createPdfkitDocument: createPdfkitDocument,
}
8 changes: 8 additions & 0 deletions packages/internal-utils/readTestResource.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var fs = require('fs');

module.exports = function (filename) {
if (filename === '.' || (/(\/|\\|\.\.)/).test(filename)) {
throw new Error(`"${filename}" is invalid filename.`);
}
return fs.readFileSync(`${__dirname}/../../resources/${filename}`);
};
12 changes: 7 additions & 5 deletions packages/placeholder-pdfkit010/dist/pdfkitAddPlaceholder.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,15 @@ export const pdfkitAddPlaceholder = ({
});

// Check if pdf already contains acroform field
const acroFormPosition = pdfBuffer.lastIndexOf('/Type /AcroForm');
const isAcroFormExists = acroFormPosition !== -1;
const isAcroFormExists = typeof pdf._root.data.AcroForm !== 'undefined';
let fieldIds = [];
let acroFormId;
if (isAcroFormExists) {
/* FIXME: We're working with a PDFDocument.
* Needing to work with strings here doesn't make sense.
*/

const acroFormPosition = pdfBuffer.lastIndexOf('/Type /AcroForm');
let acroFormStart = acroFormPosition;
// 10 is the distance between "/Type /AcroForm" and AcroFrom ID
const charsUntilIdEnd = 10;
Expand All @@ -72,19 +76,17 @@ export const pdfkitAddPlaceholder = ({
// 12 is a enough space to find the "\n"
// (generally it's 2 or 3, but I'm giving a big space though)
const maxAcroFormIdLength = 12;
let foundAcroFormId = '';
let index = charsUntilIdEnd + 1;
for (index; index < charsUntilIdEnd + maxAcroFormIdLength; index += 1) {
const acroFormIdString = pdfBuffer.slice(acroFormPosition - index, acroFormIdEnd).toString();
if (acroFormIdString[0] === '\n') {
break;
}
foundAcroFormId = acroFormIdString;
acroFormStart = acroFormPosition - index;
}
const pdfSlice = pdfBuffer.slice(acroFormStart);
const acroForm = pdfSlice.slice(0, pdfSlice.indexOf('endobj')).toString();
acroFormId = parseInt(foundAcroFormId);
acroFormId = parseInt(pdf._root.data.AcroForm.toString());
const acroFormFields = acroForm.slice(acroForm.indexOf('/Fields [') + 9, acroForm.indexOf(']'));
fieldIds = acroFormFields.split(' ').filter((element, i) => i % 3 === 0).map(fieldId => new PDFKitReferenceMock(fieldId));
}
Expand Down
13 changes: 13 additions & 0 deletions packages/placeholder-pdfkit010/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
const sharedConfig = require('../../jest.config.base');
module.exports = {
...sharedConfig,
coveragePathIgnorePatterns: [
...sharedConfig.coveragePathIgnorePatterns,
'/src/pdfkit/',
],
coverageThreshold: {
...sharedConfig.coverageThreshold,
'**/pdfkitAddPlaceholder.js': {
functions: 100,
lines: 96.77,
statements: 96.77,
branches: 88.88,
}
}
};
3 changes: 2 additions & 1 deletion packages/placeholder-pdfkit010/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@babel/plugin-syntax-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.4.2",
"@signpdf/eslint-config": "*",
"@signpdf/internal-utils": "*",
"@types/node": ">=12.0.0",
"@types/node-forge": "^1.2.1",
"assertion-error": "^1.1.0",
Expand All @@ -68,4 +69,4 @@
"pdfkit": "^0.10.0",
"typescript": "^5.2.2"
}
}
}
14 changes: 7 additions & 7 deletions packages/placeholder-pdfkit010/src/pdfkitAddPlaceholder.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,16 @@ export const pdfkitAddPlaceholder = ({
});

// Check if pdf already contains acroform field
const acroFormPosition = pdfBuffer.lastIndexOf('/Type /AcroForm');
const isAcroFormExists = acroFormPosition !== -1;
const isAcroFormExists = typeof pdf._root.data.AcroForm !== 'undefined';
let fieldIds = [];
let acroFormId;

if (isAcroFormExists) {
/* FIXME: We're working with a PDFDocument.
* Needing to work with strings here doesn't make sense.
*/

const acroFormPosition = pdfBuffer.lastIndexOf('/Type /AcroForm');
let acroFormStart = acroFormPosition;
// 10 is the distance between "/Type /AcroForm" and AcroFrom ID
const charsUntilIdEnd = 10;
Expand All @@ -79,23 +83,19 @@ export const pdfkitAddPlaceholder = ({
// 12 is a enough space to find the "\n"
// (generally it's 2 or 3, but I'm giving a big space though)
const maxAcroFormIdLength = 12;
let foundAcroFormId = '';
let index = charsUntilIdEnd + 1;
for (index; index < charsUntilIdEnd + maxAcroFormIdLength; index += 1) {
const acroFormIdString = pdfBuffer
.slice(acroFormPosition - index, acroFormIdEnd).toString();

if (acroFormIdString[0] === '\n') {
break;
}

foundAcroFormId = acroFormIdString;
acroFormStart = acroFormPosition - index;
}

const pdfSlice = pdfBuffer.slice(acroFormStart);
const acroForm = pdfSlice.slice(0, pdfSlice.indexOf('endobj')).toString();
acroFormId = parseInt(foundAcroFormId);
acroFormId = parseInt(pdf._root.data.AcroForm.toString());

const acroFormFields = acroForm.slice(acroForm.indexOf('/Fields [') + 9, acroForm.indexOf(']'));
fieldIds = acroFormFields
Expand Down
64 changes: 35 additions & 29 deletions packages/placeholder-pdfkit010/src/pdfkitAddPlaceholder.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PDFDocument from 'pdfkit';
import {SUBFILTER_ETSI_CADES_DETACHED} from '@signpdf/utils';
import {createPdfkitDocument} from '@signpdf/internal-utils';
import {pdfkitAddPlaceholder} from './pdfkitAddPlaceholder';
import PDFObject from './pdfkit/pdfobject';

Expand All @@ -11,13 +11,7 @@ describe(pdfkitAddPlaceholder, () => {
};

it('adds placeholder to PDFKit document', () => {
const pdf = new PDFDocument({
autoFirstPage: true,
size: 'A4',
layout: 'portrait',
bufferPages: true,
});
pdf.info.CreationDate = '';
const {pdf} = createPdfkitDocument();

const refs = pdfkitAddPlaceholder({
...defaults,
Expand All @@ -40,13 +34,7 @@ describe(pdfkitAddPlaceholder, () => {
});

it('placeholder contains reason, contactInfo, name, location', () => {
const pdf = new PDFDocument({
autoFirstPage: true,
size: 'A4',
layout: 'portrait',
bufferPages: true,
});
pdf.info.CreationDate = '';
const {pdf} = createPdfkitDocument();

const refs = pdfkitAddPlaceholder({
pdf,
Expand All @@ -69,13 +57,7 @@ describe(pdfkitAddPlaceholder, () => {
});

it('placeholder contains default values for contactInfo, name, location', () => {
const pdf = new PDFDocument({
autoFirstPage: true,
size: 'A4',
layout: 'portrait',
bufferPages: true,
});
pdf.info.CreationDate = '';
const {pdf} = createPdfkitDocument();

const refs = pdfkitAddPlaceholder({
...defaults,
Expand All @@ -99,13 +81,7 @@ describe(pdfkitAddPlaceholder, () => {
});

it('allows defining signature SubFilter', () => {
const pdf = new PDFDocument({
autoFirstPage: true,
size: 'A4',
layout: 'portrait',
bufferPages: true,
});
pdf.info.CreationDate = '';
const {pdf} = createPdfkitDocument();

const refs = pdfkitAddPlaceholder({
...defaults,
Expand All @@ -126,4 +102,34 @@ describe(pdfkitAddPlaceholder, () => {
expect(PDFObject.convert(widgetData.Reason)).toEqual('(test reason)');
expect(widgetData.SubFilter).toEqual('ETSI.CAdES.detached');
});

it('adds placeholder to PDFKit document when AcroForm is already there', () => {
const {pdf} = createPdfkitDocument();
const form = pdf.ref({
Type: 'AcroForm',
SigFlags: 3,
Fields: [],
});
// eslint-disable-next-line no-underscore-dangle
pdf._root.data.AcroForm = form;

const refs = pdfkitAddPlaceholder({
...defaults,
pdf,
pdfBuffer: Buffer.from([pdf]),
});
expect(Object.keys(refs)).toEqual(expect.arrayContaining([
'signature',
'form',
'widget',
]));
expect(pdf.page.dictionary.data.Annots).toHaveLength(1);
expect(pdf.page.dictionary.data.Annots[0].data.Subtype).toEqual('Widget');
expect(pdf.page.dictionary.data.Annots[0].data.V.data.ByteRange).toEqual([
0,
'**********',
'**********',
'**********',
]);
});
});
50 changes: 6 additions & 44 deletions packages/signpdf/src/signpdf.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import PDFDocument from 'pdfkit';
import forge from 'node-forge';
import {readTestResource} from '@signpdf/internal-utils';
import {readTestResource, createPdfkitDocument} from '@signpdf/internal-utils';
import {pdfkitAddPlaceholder} from '@signpdf/placeholder-pdfkit010';
import {plainAddPlaceholder} from '@signpdf/placeholder-plain';
import {
Expand All @@ -14,52 +13,13 @@ import signer from './signpdf';
* Returns a Promise that is resolved with the resulting Buffer of the PDFDocument.
* @returns {Promise<Buffer>}
*/
const createPdf = (params) => new Promise((resolve) => {
const createPdf = (params) => {
const requestParams = {
placeholder: {
contactInfo: '[email protected]',
name: 'test name',
location: 'test Location',
},
text: 'node-signpdf',
addSignaturePlaceholder: true,
pages: 1,
layout: 'portrait',
...params,
};

const pdf = new PDFDocument({
autoFirstPage: false,
size: 'A4',
layout: requestParams.layout,
bufferPages: true,
});
pdf.info.CreationDate = '';

if (requestParams.pages < 1) {
requestParams.pages = 1;
}

// Add some content to the page(s)
for (let i = 0; i < requestParams.pages; i += 1) {
pdf
.addPage()
.fillColor('#333')
.fontSize(25)
.moveDown()
.text(requestParams.text)
.save();
}

// Collect the ouput PDF
// and, when done, resolve with it stored in a Buffer
const pdfChunks = [];
pdf.on('data', (data) => {
pdfChunks.push(data);
});
pdf.on('end', () => {
resolve(Buffer.concat(pdfChunks));
});
const {pdf, ended} = createPdfkitDocument(params);

if (requestParams.addSignaturePlaceholder) {
// Externally (to PDFKit) add the signature placeholder.
Expand All @@ -77,7 +37,9 @@ const createPdf = (params) => new Promise((resolve) => {
// Also end the PDFDocument stream.
// See pdf.on('end'... on how it is then converted to Buffer.
pdf.end();
});

return ended;
};

describe('Test signing', () => {
it('expects PDF to be Buffer', () => {
Expand Down

0 comments on commit d6b4629

Please sign in to comment.