node-signpdf
Advanced tools
Comparing version
# CHANGELOG | ||
## [1.5.0] | ||
* Reworked reading xref table; | ||
* Shifted minimum Node from 10 to 12; | ||
* Added Husky; | ||
* Upgraded dependencies; | ||
## [1.4.1] | ||
@@ -4,0 +11,0 @@ |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.SUBFILTER_ETSI_CADES_DETACHED = exports.SUBFILTER_ADOBE_X509_SHA1 = exports.SUBFILTER_ADOBE_PKCS7_SHA1 = exports.SUBFILTER_ADOBE_PKCS7_DETACHED = exports.DEFAULT_BYTE_RANGE_PLACEHOLDER = exports.DEFAULT_SIGNATURE_LENGTH = void 0; | ||
exports.SUBFILTER_ETSI_CADES_DETACHED = exports.SUBFILTER_ADOBE_X509_SHA1 = exports.SUBFILTER_ADOBE_PKCS7_SHA1 = exports.SUBFILTER_ADOBE_PKCS7_DETACHED = exports.DEFAULT_SIGNATURE_LENGTH = exports.DEFAULT_BYTE_RANGE_PLACEHOLDER = void 0; | ||
const DEFAULT_SIGNATURE_LENGTH = 8192; | ||
@@ -9,0 +9,0 @@ exports.DEFAULT_SIGNATURE_LENGTH = DEFAULT_SIGNATURE_LENGTH; |
@@ -12,2 +12,8 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "findByteRange", { | ||
enumerable: true, | ||
get: function () { | ||
return _findByteRange.default; | ||
} | ||
}); | ||
Object.defineProperty(exports, "pdfkitAddPlaceholder", { | ||
@@ -31,8 +37,2 @@ enumerable: true, | ||
}); | ||
Object.defineProperty(exports, "findByteRange", { | ||
enumerable: true, | ||
get: function () { | ||
return _findByteRange.default; | ||
} | ||
}); | ||
@@ -39,0 +39,0 @@ var _extractSignature = _interopRequireDefault(require("./extractSignature")); |
@@ -21,6 +21,6 @@ "use strict"; | ||
let slice = pdf.slice(offset); | ||
slice = slice.slice(0, slice.indexOf('endobj')); // FIXME: What if it is a stream? | ||
slice = slice.slice(0, slice.indexOf('endobj', 'utf8')); // FIXME: What if it is a stream? | ||
slice = slice.slice(slice.indexOf('<<') + 2); | ||
slice = slice.slice(0, slice.lastIndexOf('>>')); | ||
slice = slice.slice(slice.indexOf('<<', 'utf8') + 2); | ||
slice = slice.slice(0, slice.lastIndexOf('>>', 'utf8')); | ||
return slice; | ||
@@ -27,0 +27,0 @@ }; |
@@ -6,54 +6,64 @@ "use strict"; | ||
}); | ||
exports.default = void 0; | ||
exports.getXref = exports.getLastTrailerPosition = exports.getFullXrefTable = exports.default = void 0; | ||
const parseTrailerXref = (prev, curr) => { | ||
const isObjectId = curr.split(' ').length === 2; | ||
var _SignPdfError = _interopRequireDefault(require("../../SignPdfError")); | ||
if (isObjectId) { | ||
const [id] = curr.split(' '); | ||
return { ...prev, | ||
[id]: undefined | ||
}; | ||
} | ||
var _xrefToRefMap = _interopRequireDefault(require("./xrefToRefMap")); | ||
const [offset] = curr.split(' '); | ||
const prevId = Object.keys(prev).find(id => prev[id] === undefined); | ||
return { ...prev, | ||
[prevId]: parseInt(offset) | ||
}; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
const getLastTrailerPosition = pdf => { | ||
const trailerStart = pdf.lastIndexOf(Buffer.from('trailer', 'utf8')); | ||
const trailer = pdf.slice(trailerStart, pdf.length - 6); | ||
const xRefPosition = trailer.slice(trailer.lastIndexOf(Buffer.from('startxref', 'utf8')) + 10).toString(); | ||
return parseInt(xRefPosition); | ||
}; | ||
const parseRootXref = (prev, l, i) => { | ||
const element = l.split(' ')[0]; | ||
const isPageObject = parseInt(element) === 0 && element.length > 3; | ||
exports.getLastTrailerPosition = getLastTrailerPosition; | ||
if (isPageObject) { | ||
return { ...prev, | ||
0: 0 | ||
}; | ||
const getXref = (pdf, position) => { | ||
let refTable = pdf.slice(position); // slice starting from where xref starts | ||
const realPosition = refTable.indexOf(Buffer.from('xref', 'utf8')); | ||
if (realPosition === -1) { | ||
throw new _SignPdfError.default(`Could not find xref anywhere at or after ${position}.`, _SignPdfError.default.TYPE_PARSE); | ||
} | ||
let [offset] = l.split(' '); | ||
offset = parseInt(offset); | ||
return { ...prev, | ||
[i - 1]: offset | ||
}; | ||
}; | ||
if (realPosition > 0) { | ||
const prefix = refTable.slice(0, realPosition); | ||
const getLastTrailerPosition = pdf => { | ||
const trailerStart = pdf.lastIndexOf('trailer'); | ||
const trailer = pdf.slice(trailerStart, pdf.length - 6); | ||
const xRefPosition = trailer.slice(trailer.lastIndexOf('startxref') + 10).toString(); | ||
return parseInt(xRefPosition); | ||
}; | ||
if (prefix.toString().replace(/\s*/g, '') !== '') { | ||
throw new _SignPdfError.default(`Expected xref at ${position} but found other content.`, _SignPdfError.default.TYPE_PARSE); | ||
} | ||
} | ||
const getXref = (pdf, position) => { | ||
let refTable = pdf.slice(position); | ||
refTable = refTable.slice(4); | ||
refTable = refTable.slice(refTable.indexOf('\n') + 1); | ||
const size = refTable.toString().split('/Size')[1]; | ||
const nextEofPosition = refTable.indexOf(Buffer.from('%%EOF', 'utf8')); | ||
if (nextEofPosition === -1) { | ||
throw new _SignPdfError.default('Expected EOF after xref and trailer but could not find one.', _SignPdfError.default.TYPE_PARSE); | ||
} | ||
refTable = refTable.slice(0, nextEofPosition); | ||
refTable = refTable.slice(realPosition + 4); // move ahead with the "xref" | ||
refTable = refTable.slice(refTable.indexOf('\n') + 1); // move after the next new line | ||
// extract the size | ||
let size = refTable.toString().split('/Size')[1]; | ||
if (!size) { | ||
throw new _SignPdfError.default('Size not found in xref table.', _SignPdfError.default.TYPE_PARSE); | ||
} | ||
size = /^\s*(\d+)/.exec(size); | ||
if (size === null) { | ||
throw new _SignPdfError.default('Failed to parse size of xref table.', _SignPdfError.default.TYPE_PARSE); | ||
} | ||
size = parseInt(size[1]); | ||
const [objects, infos] = refTable.toString().split('trailer'); | ||
const isContainingPrev = infos.split('/Prev')[1] != null; | ||
let prev; | ||
let reducer; | ||
@@ -65,8 +75,5 @@ if (isContainingPrev) { | ||
prev = prevPosition; | ||
reducer = parseTrailerXref; | ||
} else { | ||
reducer = parseRootXref; | ||
} | ||
const xRefContent = objects.split('\n').filter(l => l !== '').reduce(reducer, {}); | ||
const xRefContent = (0, _xrefToRefMap.default)(objects); | ||
return { | ||
@@ -79,2 +86,4 @@ size, | ||
exports.getXref = getXref; | ||
const getFullXrefTable = pdf => { | ||
@@ -90,5 +99,3 @@ const lastTrailerPosition = getLastTrailerPosition(pdf); | ||
const partOfXrefTable = getFullXrefTable(pdfWithoutLastTrailer); | ||
const mergedXrefTable = { ...partOfXrefTable, | ||
...lastXrefTable.xRefContent | ||
}; | ||
const mergedXrefTable = new Map([...partOfXrefTable, ...lastXrefTable.xRefContent]); | ||
return mergedXrefTable; | ||
@@ -102,18 +109,12 @@ }; | ||
exports.getFullXrefTable = getFullXrefTable; | ||
const readRefTable = pdf => { | ||
const offsetsMap = new Map(); | ||
const fullXrefTable = getFullXrefTable(pdf); | ||
const startingIndex = 0; | ||
let maxOffset = 0; | ||
const maxIndex = parseInt(Object.keys(fullXrefTable).length) - 1; | ||
Object.keys(fullXrefTable).forEach(id => { | ||
const offset = parseInt(fullXrefTable[id]); | ||
maxOffset = Math.max(maxOffset, offset); | ||
offsetsMap.set(parseInt(id), offset); | ||
}); | ||
const maxIndex = Math.max(...fullXrefTable.keys()); | ||
return { | ||
maxOffset, | ||
startingIndex, | ||
maxIndex, | ||
offsets: offsetsMap | ||
offsets: fullXrefTable | ||
}; | ||
@@ -120,0 +121,0 @@ }; |
@@ -10,2 +10,3 @@ "use strict"; | ||
}; | ||
exports.SignPdf = void 0; | ||
Object.defineProperty(exports, "SignPdfError", { | ||
@@ -17,3 +18,3 @@ enumerable: true, | ||
}); | ||
exports.default = exports.SignPdf = void 0; | ||
exports.default = void 0; | ||
@@ -29,2 +30,3 @@ var _nodeForge = _interopRequireDefault(require("node-forge")); | ||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; | ||
if (key in exports && exports[key] === _helpers[key]) return; | ||
Object.defineProperty(exports, key, { | ||
@@ -43,2 +45,3 @@ enumerable: true, | ||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; | ||
if (key in exports && exports[key] === _const[key]) return; | ||
Object.defineProperty(exports, key, { | ||
@@ -45,0 +48,0 @@ enumerable: true, |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.default = exports.ERROR_VERIFY_SIGNATURE = exports.ERROR_TYPE_PARSE = exports.ERROR_TYPE_INPUT = exports.ERROR_TYPE_UNKNOWN = void 0; | ||
exports.default = exports.ERROR_VERIFY_SIGNATURE = exports.ERROR_TYPE_UNKNOWN = exports.ERROR_TYPE_PARSE = exports.ERROR_TYPE_INPUT = void 0; | ||
const ERROR_TYPE_UNKNOWN = 1; | ||
@@ -9,0 +9,0 @@ exports.ERROR_TYPE_UNKNOWN = ERROR_TYPE_UNKNOWN; |
@@ -22,2 +22,10 @@ module.exports = { | ||
], | ||
coverageThreshold: { | ||
global: { | ||
branches: 100, | ||
functions: 100, | ||
lines: 100, | ||
statements: 100, | ||
}, | ||
}, | ||
}; |
{ | ||
"name": "node-signpdf", | ||
"version": "1.4.1", | ||
"version": "1.5.0", | ||
"description": "Simple signing of PDFs in node.", | ||
@@ -27,3 +27,3 @@ "repository": { | ||
"engines": { | ||
"node": ">=8.9" | ||
"node": ">=12" | ||
}, | ||
@@ -37,7 +37,6 @@ "scripts": { | ||
"lint": "./node_modules/.bin/eslint -c .eslintrc --ignore-path .eslintignore ./", | ||
"precommit": "npm run lint", | ||
"prepush": "npm run test" | ||
"prepare": "husky install" | ||
}, | ||
"peerDependencies": { | ||
"node-forge": "^0.10.0" | ||
"node-forge": "^1.2.1" | ||
}, | ||
@@ -52,3 +51,2 @@ "devDependencies": { | ||
"assertion-error": "^1.1.0", | ||
"babel-eslint": "^10.1.0", | ||
"babel-jest": "^27.3.1", | ||
@@ -62,6 +60,7 @@ "babel-plugin-module-resolver": "^3.1.1", | ||
"eslint-plugin-jest": "^25.2.4", | ||
"husky": "^7.0.4", | ||
"jest": "^27.3.1", | ||
"node-forge": "^0.10.0", | ||
"node-forge": "^1.2.1", | ||
"pdfkit": "^0.10.0" | ||
} | ||
} |
#  | ||
[](https://badge.fury.io/js/node-signpdf) | ||
[](https://travis-ci.com/vbuch/node-signpdf) | ||
[](https://coveralls.io/github/vbuch/node-signpdf?branch=master) | ||
[](https://snyk.io/test/npm/node-signpdf) | ||
[](https://buymeacoffee.com/vbuch) | ||
 | ||
@@ -99,3 +100,3 @@ Simple signing of PDFs in node. | ||
That's where the Signer kicks in. Given a PDF and a P12 certificate a signature is generated in detached mode and is replaced in the placeholder. This is best demonstrated in [the tests](https://github.com/vbuch/node-signpdf/blob/master/src/signpdf.test.js#L100). | ||
That's where the Signer kicks in. Given a PDF and a P12 certificate a signature is generated in detached mode and is replaced in the placeholder. This is best demonstrated in [the tests](https://github.com/vbuch/node-signpdf/blob/master/src/signpdf.test.js#L122). | ||
@@ -102,0 +103,0 @@ ## Dependencies |
@@ -5,4 +5,4 @@ import * as helpers from './index'; | ||
it('Exports expected helpers', () => { | ||
expect(Object.keys(helpers)).toMatchSnapshot(); | ||
expect(Object.keys(helpers).sort()).toMatchSnapshot(); | ||
}); | ||
}); |
@@ -13,7 +13,7 @@ import getIndexFromRef from './getIndexFromRef'; | ||
let slice = pdf.slice(offset); | ||
slice = slice.slice(0, slice.indexOf('endobj')); | ||
slice = slice.slice(0, slice.indexOf('endobj', 'utf8')); | ||
// FIXME: What if it is a stream? | ||
slice = slice.slice(slice.indexOf('<<') + 2); | ||
slice = slice.slice(0, slice.lastIndexOf('>>')); | ||
slice = slice.slice(slice.indexOf('<<', 'utf8') + 2); | ||
slice = slice.slice(0, slice.lastIndexOf('>>', 'utf8')); | ||
return slice; | ||
@@ -20,0 +20,0 @@ }; |
@@ -1,46 +0,63 @@ | ||
const parseTrailerXref = (prev, curr) => { | ||
const isObjectId = curr.split(' ').length === 2; | ||
import SignPdfError from '../../SignPdfError'; | ||
import xrefToRefMap from './xrefToRefMap'; | ||
if (isObjectId) { | ||
const [id] = curr.split(' '); | ||
return {...prev, [id]: undefined}; | ||
} | ||
export const getLastTrailerPosition = (pdf) => { | ||
const trailerStart = pdf.lastIndexOf(Buffer.from('trailer', 'utf8')); | ||
const trailer = pdf.slice(trailerStart, pdf.length - 6); | ||
const [offset] = curr.split(' '); | ||
const prevId = Object.keys(prev).find((id) => prev[id] === undefined); | ||
const xRefPosition = trailer | ||
.slice(trailer.lastIndexOf(Buffer.from('startxref', 'utf8')) + 10) | ||
.toString(); | ||
return {...prev, [prevId]: parseInt(offset)}; | ||
return parseInt(xRefPosition); | ||
}; | ||
const parseRootXref = (prev, l, i) => { | ||
const element = l.split(' ')[0]; | ||
const isPageObject = parseInt(element) === 0 && element.length > 3; | ||
export const getXref = (pdf, position) => { | ||
let refTable = pdf.slice(position); // slice starting from where xref starts | ||
const realPosition = refTable.indexOf(Buffer.from('xref', 'utf8')); | ||
if (realPosition === -1) { | ||
throw new SignPdfError( | ||
`Could not find xref anywhere at or after ${position}.`, | ||
SignPdfError.TYPE_PARSE, | ||
); | ||
} | ||
if (realPosition > 0) { | ||
const prefix = refTable.slice(0, realPosition); | ||
if (prefix.toString().replace(/\s*/g, '') !== '') { | ||
throw new SignPdfError( | ||
`Expected xref at ${position} but found other content.`, | ||
SignPdfError.TYPE_PARSE, | ||
); | ||
} | ||
} | ||
if (isPageObject) { | ||
return {...prev, 0: 0}; | ||
const nextEofPosition = refTable.indexOf(Buffer.from('%%EOF', 'utf8')); | ||
if (nextEofPosition === -1) { | ||
throw new SignPdfError( | ||
'Expected EOF after xref and trailer but could not find one.', | ||
SignPdfError.TYPE_PARSE, | ||
); | ||
} | ||
refTable = refTable.slice(0, nextEofPosition); | ||
refTable = refTable.slice(realPosition + 4); // move ahead with the "xref" | ||
refTable = refTable.slice(refTable.indexOf('\n') + 1); // move after the next new line | ||
let [offset] = l.split(' '); | ||
offset = parseInt(offset); | ||
// extract the size | ||
let size = refTable.toString().split('/Size')[1]; | ||
return {...prev, [i - 1]: offset}; | ||
}; | ||
if (!size) { | ||
throw new SignPdfError( | ||
'Size not found in xref table.', | ||
SignPdfError.TYPE_PARSE, | ||
); | ||
} | ||
size = (/^\s*(\d+)/).exec(size); | ||
if (size === null) { | ||
throw new SignPdfError( | ||
'Failed to parse size of xref table.', | ||
SignPdfError.TYPE_PARSE, | ||
); | ||
} | ||
size = parseInt(size[1]); | ||
const getLastTrailerPosition = (pdf) => { | ||
const trailerStart = pdf.lastIndexOf('trailer'); | ||
const trailer = pdf.slice(trailerStart, pdf.length - 6); | ||
const xRefPosition = trailer | ||
.slice(trailer.lastIndexOf('startxref') + 10) | ||
.toString(); | ||
return parseInt(xRefPosition); | ||
}; | ||
const getXref = (pdf, position) => { | ||
let refTable = pdf.slice(position); | ||
refTable = refTable.slice(4); | ||
refTable = refTable.slice(refTable.indexOf('\n') + 1); | ||
const size = refTable.toString().split('/Size')[1]; | ||
const [objects, infos] = refTable.toString().split('trailer'); | ||
@@ -51,4 +68,2 @@ | ||
let prev; | ||
let reducer; | ||
if (isContainingPrev) { | ||
@@ -59,11 +74,5 @@ const pagesRefRegex = /Prev (\d+)/g; | ||
prev = prevPosition; | ||
reducer = parseTrailerXref; | ||
} else { | ||
reducer = parseRootXref; | ||
} | ||
const xRefContent = objects | ||
.split('\n') | ||
.filter((l) => l !== '') | ||
.reduce(reducer, {}); | ||
const xRefContent = xrefToRefMap(objects); | ||
@@ -77,3 +86,3 @@ return { | ||
const getFullXrefTable = (pdf) => { | ||
export const getFullXrefTable = (pdf) => { | ||
const lastTrailerPosition = getLastTrailerPosition(pdf); | ||
@@ -88,6 +97,6 @@ const lastXrefTable = getXref(pdf, lastTrailerPosition); | ||
const mergedXrefTable = { | ||
const mergedXrefTable = new Map([ | ||
...partOfXrefTable, | ||
...lastXrefTable.xRefContent, | ||
}; | ||
]); | ||
@@ -102,21 +111,10 @@ return mergedXrefTable; | ||
const readRefTable = (pdf) => { | ||
const offsetsMap = new Map(); | ||
const fullXrefTable = getFullXrefTable(pdf); | ||
const startingIndex = 0; | ||
const maxIndex = Math.max(...fullXrefTable.keys()); | ||
let maxOffset = 0; | ||
const maxIndex = parseInt(Object.keys(fullXrefTable).length) - 1; | ||
Object.keys(fullXrefTable).forEach((id) => { | ||
const offset = parseInt(fullXrefTable[id]); | ||
maxOffset = Math.max(maxOffset, offset); | ||
offsetsMap.set(parseInt(id), offset); | ||
}); | ||
return { | ||
maxOffset, | ||
startingIndex, | ||
maxIndex, | ||
offsets: offsetsMap, | ||
offsets: fullXrefTable, | ||
}; | ||
@@ -123,0 +121,0 @@ }; |
import fs from 'fs'; | ||
import readRefTable from './readRefTable'; | ||
import SignPdfError from '../../SignPdfError'; | ||
import readRefTable, {getXref} from './readRefTable'; | ||
describe('getXref', () => { | ||
it('Throws an error when xref is not found at position', () => { | ||
const pdf = Buffer.from('Not containing an X R E F.'); | ||
const position = 0; | ||
try { | ||
getXref(pdf, position); | ||
expect('here').not.toBe('here'); | ||
} catch (e) { | ||
expect(e instanceof SignPdfError).toBe(true); | ||
expect(e.type).toBe(SignPdfError.TYPE_PARSE); | ||
expect(e.message).toMatchSnapshot(); | ||
} | ||
}); | ||
it('Throws an error when xref is not at its expected position', () => { | ||
const pdf = Buffer.from('Contains xref but definetely not where expected.'); | ||
const position = 2; | ||
try { | ||
getXref(pdf, position); | ||
expect('here').not.toBe('here'); | ||
} catch (e) { | ||
expect(e instanceof SignPdfError).toBe(true); | ||
expect(e.type).toBe(SignPdfError.TYPE_PARSE); | ||
expect(e.message).toMatchSnapshot(); | ||
} | ||
}); | ||
it('Throws an error when size is not found', () => { | ||
const pdf = Buffer.from('xref\n and there is no Size %%EOF'); | ||
const position = 0; | ||
try { | ||
getXref(pdf, position); | ||
expect('here').not.toBe('here'); | ||
} catch (e) { | ||
expect(e instanceof SignPdfError).toBe(true); | ||
expect(e.type).toBe(SignPdfError.TYPE_PARSE); | ||
expect(e.message).toMatchSnapshot(); | ||
} | ||
}); | ||
it('Throws an error when size has unexpected value', () => { | ||
const pdf = Buffer.from('xref\n and then somewhere here there is a /Size XXXX %%EOF'); | ||
const position = 0; | ||
try { | ||
getXref(pdf, position); | ||
expect('here').not.toBe('here'); | ||
} catch (e) { | ||
expect(e instanceof SignPdfError).toBe(true); | ||
expect(e.type).toBe(SignPdfError.TYPE_PARSE); | ||
expect(e.message).toMatchSnapshot(); | ||
} | ||
}); | ||
it('Throws an error when next EOF is not found', () => { | ||
const pdf = Buffer.from('xref\n then /Size 123 and then but no EOF'); | ||
const position = 0; | ||
try { | ||
getXref(pdf, position); | ||
expect('here').not.toBe('here'); | ||
} catch (e) { | ||
expect(e instanceof SignPdfError).toBe(true); | ||
expect(e.type).toBe(SignPdfError.TYPE_PARSE); | ||
expect(e.message).toMatchSnapshot(); | ||
} | ||
}); | ||
}); | ||
describe('readRefTable', () => { | ||
@@ -5,0 +69,0 @@ it('Expects to merge correctly the refTable of resources', () => { |
@@ -19,2 +19,3 @@ import PDFDocument from 'pdfkit'; | ||
pages: 1, | ||
layout: 'portrait', | ||
...params, | ||
@@ -26,3 +27,3 @@ }; | ||
size: 'A4', | ||
layout: 'portrait', | ||
layout: requestParams.layout, | ||
bufferPages: true, | ||
@@ -114,3 +115,5 @@ }); | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
@@ -127,3 +130,5 @@ signer.sign(pdfBuffer, p12Buffer); | ||
let pdfBuffer = await createPdf(); | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
@@ -137,4 +142,19 @@ pdfBuffer = signer.sign(pdfBuffer, p12Buffer); | ||
}); | ||
it('signs a landscape PDF', async () => { | ||
let pdfBuffer = await createPdf({layout: 'landscape'}); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
pdfBuffer = signer.sign(pdfBuffer, p12Buffer); | ||
expect(pdfBuffer instanceof Buffer).toBe(true); | ||
const {signature, signedData} = extractSignature(pdfBuffer); | ||
expect(typeof signature === 'string').toBe(true); | ||
expect(signedData instanceof Buffer).toBe(true); | ||
}); | ||
it('signs detached', async () => { | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
@@ -153,3 +173,5 @@ let pdfBuffer = await createPdf({text: 'Some text'}); | ||
it('signs a ready pdf', async () => { | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
let pdfBuffer = fs.readFileSync(`${__dirname}/../resources/w3dummy.pdf`); | ||
@@ -167,5 +189,24 @@ pdfBuffer = plainAddPlaceholder({ | ||
}); | ||
it('Signs the resource from issue 158', async () => { | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
let pdfBuffer = fs.readFileSync(`${__dirname}/../resources/issue-158-test.pdf`); | ||
pdfBuffer = plainAddPlaceholder({ | ||
pdfBuffer, | ||
reason: 'I have reviewed it.', | ||
signatureLength: 1612, | ||
}); | ||
pdfBuffer = signer.sign(pdfBuffer, p12Buffer); | ||
const {signature, signedData} = extractSignature(pdfBuffer); | ||
expect(typeof signature === 'string').toBe(true); | ||
expect(signedData instanceof Buffer).toBe(true); | ||
}); | ||
it('signs a ready pdf that does not have Annots', async () => { | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
let pdfBuffer = fs.readFileSync(`${__dirname}/../resources/no-annotations.pdf`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
let pdfBuffer = fs.readFileSync( | ||
`${__dirname}/../resources/no-annotations.pdf`, | ||
); | ||
pdfBuffer = plainAddPlaceholder({ | ||
@@ -183,4 +224,8 @@ pdfBuffer, | ||
it('signs a ready pdf that does not have metadata', async () => { | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
let pdfBuffer = fs.readFileSync(`${__dirname}/../resources/no-metadata.pdf`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
let pdfBuffer = fs.readFileSync( | ||
`${__dirname}/../resources/no-metadata.pdf`, | ||
); | ||
@@ -199,4 +244,8 @@ pdfBuffer = plainAddPlaceholder({ | ||
it('signs a ready pdf two times', async () => { | ||
const secondP12Buffer = fs.readFileSync(`${__dirname}/../resources/withpass.p12`); | ||
let signedPdfBuffer = fs.readFileSync(`${__dirname}/../resources/signed-once.pdf`); | ||
const secondP12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/withpass.p12`, | ||
); | ||
let signedPdfBuffer = fs.readFileSync( | ||
`${__dirname}/../resources/signed-once.pdf`, | ||
); | ||
signedPdfBuffer = plainAddPlaceholder({ | ||
@@ -208,3 +257,5 @@ pdfBuffer: signedPdfBuffer, | ||
}); | ||
signedPdfBuffer = signer.sign(signedPdfBuffer, secondP12Buffer, {passphrase: 'node-signpdf'}); | ||
signedPdfBuffer = signer.sign(signedPdfBuffer, secondP12Buffer, { | ||
passphrase: 'node-signpdf', | ||
}); | ||
const {signature, signedData} = extractSignature(signedPdfBuffer, 2); | ||
@@ -218,3 +269,5 @@ expect(typeof signature === 'string').toBe(true); | ||
}); | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
@@ -228,3 +281,5 @@ pdfBuffer = signer.sign(pdfBuffer, p12Buffer); | ||
const secondP12Buffer = fs.readFileSync(`${__dirname}/../resources/withpass.p12`); | ||
const secondP12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/withpass.p12`, | ||
); | ||
pdfBuffer = plainAddPlaceholder({ | ||
@@ -236,3 +291,5 @@ pdfBuffer, | ||
}); | ||
pdfBuffer = signer.sign(pdfBuffer, secondP12Buffer, {passphrase: 'node-signpdf'}); | ||
pdfBuffer = signer.sign(pdfBuffer, secondP12Buffer, { | ||
passphrase: 'node-signpdf', | ||
}); | ||
expect(pdfBuffer instanceof Buffer).toBe(true); | ||
@@ -248,4 +305,8 @@ | ||
it('signs a ready pdf containing a link', async () => { | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
let pdfBuffer = fs.readFileSync(`${__dirname}/../resources/including-a-link.pdf`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
let pdfBuffer = fs.readFileSync( | ||
`${__dirname}/../resources/including-a-link.pdf`, | ||
); | ||
pdfBuffer = plainAddPlaceholder({ | ||
@@ -278,7 +339,5 @@ pdfBuffer, | ||
pdfBuffer = signer.sign( | ||
pdfBuffer, | ||
p12Buffer, | ||
{passphrase: 'node-signpdf'}, | ||
); | ||
pdfBuffer = signer.sign(pdfBuffer, p12Buffer, { | ||
passphrase: 'node-signpdf', | ||
}); | ||
expect(pdfBuffer instanceof Buffer).toBe(true); | ||
@@ -295,7 +354,3 @@ | ||
try { | ||
signer.sign( | ||
pdfBuffer, | ||
p12Buffer, | ||
{passphrase: 'Wrong passphrase'}, | ||
); | ||
signer.sign(pdfBuffer, p12Buffer, {passphrase: 'Wrong passphrase'}); | ||
expect('here').not.toBe('here'); | ||
@@ -334,6 +389,3 @@ } catch (e) { | ||
try { | ||
signer.sign( | ||
pdfBuffer, | ||
p12Buffer, | ||
); | ||
signer.sign(pdfBuffer, p12Buffer); | ||
expect('here').not.toBe('here'); | ||
@@ -349,3 +401,5 @@ } catch (e) { | ||
it('error when final key inside trailer dictionary is /Root', async () => { | ||
let pdfBuffer = fs.readFileSync(`${__dirname}/../resources/w3dummy-different-trailer.pdf`); | ||
let pdfBuffer = fs.readFileSync( | ||
`${__dirname}/../resources/w3dummy-different-trailer.pdf`, | ||
); | ||
pdfBuffer = plainAddPlaceholder({ | ||
@@ -356,3 +410,5 @@ pdfBuffer, | ||
}); | ||
const trailer = pdfBuffer.slice(pdfBuffer.lastIndexOf('trailer')).toString(); | ||
const trailer = pdfBuffer | ||
.slice(pdfBuffer.lastIndexOf('trailer')) | ||
.toString(); | ||
// the trailer should contain only one startxref | ||
@@ -364,3 +420,5 @@ expect(trailer.match(/startxref/g).length).toBe(1); | ||
const pdfBuffer = fs.readFileSync(`${__dirname}/../resources/signed.pdf`); | ||
const p12Buffer = fs.readFileSync(`${__dirname}/../resources/certificate.p12`); | ||
const p12Buffer = fs.readFileSync( | ||
`${__dirname}/../resources/certificate.p12`, | ||
); | ||
@@ -367,0 +425,0 @@ signer.sign(pdfBuffer, p12Buffer); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1116211
160.75%101
8.6%3119
12.19%117
0.86%