mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 00:32:43 +10:00
Apply prettier config to all files
This commit is contained in:
@ -1,17 +1,10 @@
|
||||
import { PDFDocument, PDFHexString, PDFName, PDFNumber, PDFString } from "pdf-lib";
|
||||
|
||||
const fs = require("fs");
|
||||
// Local copy of Node SignPDF because https://github.com/vbuch/node-signpdf/pull/187 was not published in NPM yet. Can be switched to npm packge.
|
||||
const signer = require("./node-signpdf/dist/signpdf");
|
||||
import {
|
||||
PDFDocument,
|
||||
PDFName,
|
||||
PDFNumber,
|
||||
PDFHexString,
|
||||
PDFString,
|
||||
} from "pdf-lib";
|
||||
|
||||
export const addDigitalSignature = async (
|
||||
documentAsBase64: string
|
||||
): Promise<string> => {
|
||||
export const addDigitalSignature = async (documentAsBase64: string): Promise<string> => {
|
||||
// Custom code to add Byterange to PDF
|
||||
const PDFArrayCustom = require("./PDFArrayCustom");
|
||||
const pdfBuffer = Buffer.from(documentAsBase64, "base64");
|
||||
|
||||
@ -1 +1 @@
|
||||
export { signDocument } from "./signDocument";
|
||||
export { signDocument } from "./signDocument";
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = exports.ERROR_VERIFY_SIGNATURE = exports.ERROR_TYPE_UNKNOWN = exports.ERROR_TYPE_PARSE = exports.ERROR_TYPE_INPUT = 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;
|
||||
exports.ERROR_TYPE_UNKNOWN = ERROR_TYPE_UNKNOWN;
|
||||
const ERROR_TYPE_INPUT = 2;
|
||||
@ -18,13 +23,11 @@ class SignPdfError extends Error {
|
||||
super(msg);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
} // Shorthand
|
||||
|
||||
|
||||
SignPdfError.TYPE_UNKNOWN = ERROR_TYPE_UNKNOWN;
|
||||
SignPdfError.TYPE_INPUT = ERROR_TYPE_INPUT;
|
||||
SignPdfError.TYPE_PARSE = ERROR_TYPE_PARSE;
|
||||
SignPdfError.VERIFY_SIGNATURE = ERROR_VERIFY_SIGNATURE;
|
||||
var _default = SignPdfError;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,18 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
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;
|
||||
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;
|
||||
exports.DEFAULT_SIGNATURE_LENGTH = DEFAULT_SIGNATURE_LENGTH;
|
||||
const DEFAULT_BYTE_RANGE_PLACEHOLDER = '**********';
|
||||
const DEFAULT_BYTE_RANGE_PLACEHOLDER = "**********";
|
||||
exports.DEFAULT_BYTE_RANGE_PLACEHOLDER = DEFAULT_BYTE_RANGE_PLACEHOLDER;
|
||||
const SUBFILTER_ADOBE_PKCS7_DETACHED = 'adbe.pkcs7.detached';
|
||||
const SUBFILTER_ADOBE_PKCS7_DETACHED = "adbe.pkcs7.detached";
|
||||
exports.SUBFILTER_ADOBE_PKCS7_DETACHED = SUBFILTER_ADOBE_PKCS7_DETACHED;
|
||||
const SUBFILTER_ADOBE_PKCS7_SHA1 = 'adbe.pkcs7.sha1';
|
||||
const SUBFILTER_ADOBE_PKCS7_SHA1 = "adbe.pkcs7.sha1";
|
||||
exports.SUBFILTER_ADOBE_PKCS7_SHA1 = SUBFILTER_ADOBE_PKCS7_SHA1;
|
||||
const SUBFILTER_ADOBE_X509_SHA1 = 'adbe.x509.rsa.sha1';
|
||||
const SUBFILTER_ADOBE_X509_SHA1 = "adbe.x509.rsa.sha1";
|
||||
exports.SUBFILTER_ADOBE_X509_SHA1 = SUBFILTER_ADOBE_X509_SHA1;
|
||||
const SUBFILTER_ETSI_CADES_DETACHED = 'ETSI.CAdES.detached';
|
||||
exports.SUBFILTER_ETSI_CADES_DETACHED = SUBFILTER_ETSI_CADES_DETACHED;
|
||||
const SUBFILTER_ETSI_CADES_DETACHED = "ETSI.CAdES.detached";
|
||||
exports.SUBFILTER_ETSI_CADES_DETACHED = SUBFILTER_ETSI_CADES_DETACHED;
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _SignPdfError = _interopRequireDefault(require("../SignPdfError"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
const getSubstringIndex = (str, substring, n) => {
|
||||
let times = 0;
|
||||
@ -30,42 +32,49 @@ const getSubstringIndex = (str, substring, n) => {
|
||||
* @returns {Object} {ByteRange: Number[], signature: Buffer, signedData: Buffer}
|
||||
*/
|
||||
|
||||
|
||||
const extractSignature = (pdf, signatureCount = 1) => {
|
||||
if (!(pdf instanceof Buffer)) {
|
||||
throw new _SignPdfError.default('PDF expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
|
||||
throw new _SignPdfError.default("PDF expected as Buffer.", _SignPdfError.default.TYPE_INPUT);
|
||||
} // const byteRangePos = pdf.indexOf('/ByteRange [');
|
||||
|
||||
|
||||
const byteRangePos = getSubstringIndex(pdf, '/ByteRange [', signatureCount);
|
||||
const byteRangePos = getSubstringIndex(pdf, "/ByteRange [", signatureCount);
|
||||
|
||||
if (byteRangePos === -1) {
|
||||
throw new _SignPdfError.default('Failed to locate ByteRange.', _SignPdfError.default.TYPE_PARSE);
|
||||
throw new _SignPdfError.default("Failed to locate ByteRange.", _SignPdfError.default.TYPE_PARSE);
|
||||
}
|
||||
|
||||
const byteRangeEnd = pdf.indexOf(']', byteRangePos);
|
||||
const byteRangeEnd = pdf.indexOf("]", byteRangePos);
|
||||
|
||||
if (byteRangeEnd === -1) {
|
||||
throw new _SignPdfError.default('Failed to locate the end of the ByteRange.', _SignPdfError.default.TYPE_PARSE);
|
||||
throw new _SignPdfError.default(
|
||||
"Failed to locate the end of the ByteRange.",
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
|
||||
const byteRange = pdf.slice(byteRangePos, byteRangeEnd + 1).toString();
|
||||
const matches = /\/ByteRange \[(\d+) +(\d+) +(\d+) +(\d+) *\]/.exec(byteRange);
|
||||
|
||||
if (matches === null) {
|
||||
throw new _SignPdfError.default('Failed to parse the ByteRange.', _SignPdfError.default.TYPE_PARSE);
|
||||
throw new _SignPdfError.default("Failed to parse the ByteRange.", _SignPdfError.default.TYPE_PARSE);
|
||||
}
|
||||
|
||||
const ByteRange = matches.slice(1).map(Number);
|
||||
const signedData = Buffer.concat([pdf.slice(ByteRange[0], ByteRange[0] + ByteRange[1]), pdf.slice(ByteRange[2], ByteRange[2] + ByteRange[3])]);
|
||||
const signatureHex = pdf.slice(ByteRange[0] + ByteRange[1] + 1, ByteRange[2]).toString('binary').replace(/(?:00|>)+$/, '');
|
||||
const signature = Buffer.from(signatureHex, 'hex').toString('binary');
|
||||
const signedData = Buffer.concat([
|
||||
pdf.slice(ByteRange[0], ByteRange[0] + ByteRange[1]),
|
||||
pdf.slice(ByteRange[2], ByteRange[2] + ByteRange[3]),
|
||||
]);
|
||||
const signatureHex = pdf
|
||||
.slice(ByteRange[0] + ByteRange[1] + 1, ByteRange[2])
|
||||
.toString("binary")
|
||||
.replace(/(?:00|>)+$/, "");
|
||||
const signature = Buffer.from(signatureHex, "hex").toString("binary");
|
||||
return {
|
||||
ByteRange: matches.slice(1, 5).map(Number),
|
||||
signature,
|
||||
signedData
|
||||
signedData,
|
||||
};
|
||||
};
|
||||
|
||||
var _default = extractSignature;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
@ -9,7 +9,9 @@ var _SignPdfError = _interopRequireDefault(require("../SignPdfError"));
|
||||
|
||||
var _const = require("./const");
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds ByteRange information within a given PDF Buffer if one exists
|
||||
@ -17,25 +19,32 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
||||
* @param {Buffer} pdf
|
||||
* @returns {Object} {byteRangePlaceholder: String, byteRangeStrings: String[], byteRange: String[]}
|
||||
*/
|
||||
const findByteRange = pdf => {
|
||||
const findByteRange = (pdf) => {
|
||||
if (!(pdf instanceof Buffer)) {
|
||||
throw new _SignPdfError.default('PDF expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
|
||||
throw new _SignPdfError.default("PDF expected as Buffer.", _SignPdfError.default.TYPE_INPUT);
|
||||
}
|
||||
|
||||
const byteRangeStrings = pdf.toString().match(/\/ByteRange\s*\[{1}\s*(?:(?:\d*|\/\*{10})\s+){3}(?:\d+|\/\*{10}){1}\s*]{1}/g);
|
||||
const byteRangeStrings = pdf
|
||||
.toString()
|
||||
.match(/\/ByteRange\s*\[{1}\s*(?:(?:\d*|\/\*{10})\s+){3}(?:\d+|\/\*{10}){1}\s*]{1}/g);
|
||||
|
||||
if (!byteRangeStrings) {
|
||||
throw new _SignPdfError.default('No ByteRangeStrings found within PDF buffer', _SignPdfError.default.TYPE_PARSE);
|
||||
throw new _SignPdfError.default(
|
||||
"No ByteRangeStrings found within PDF buffer",
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
|
||||
const byteRangePlaceholder = byteRangeStrings.find(s => s.includes(`/${_const.DEFAULT_BYTE_RANGE_PLACEHOLDER}`));
|
||||
const byteRanges = byteRangeStrings.map(brs => brs.match(/[^[\s]*(?:\d|\/\*{10})/g));
|
||||
const byteRangePlaceholder = byteRangeStrings.find((s) =>
|
||||
s.includes(`/${_const.DEFAULT_BYTE_RANGE_PLACEHOLDER}`)
|
||||
);
|
||||
const byteRanges = byteRangeStrings.map((brs) => brs.match(/[^[\s]*(?:\d|\/\*{10})/g));
|
||||
return {
|
||||
byteRangePlaceholder,
|
||||
byteRangeStrings,
|
||||
byteRanges
|
||||
byteRanges,
|
||||
};
|
||||
};
|
||||
|
||||
var _default = findByteRange;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,37 +1,37 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
Object.defineProperty(exports, "extractSignature", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _extractSignature.default;
|
||||
}
|
||||
},
|
||||
});
|
||||
Object.defineProperty(exports, "findByteRange", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _findByteRange.default;
|
||||
}
|
||||
},
|
||||
});
|
||||
Object.defineProperty(exports, "pdfkitAddPlaceholder", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _pdfkitAddPlaceholder.default;
|
||||
}
|
||||
},
|
||||
});
|
||||
Object.defineProperty(exports, "plainAddPlaceholder", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _plainAddPlaceholder.default;
|
||||
}
|
||||
},
|
||||
});
|
||||
Object.defineProperty(exports, "removeTrailingNewLine", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _removeTrailingNewLine.default;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var _extractSignature = _interopRequireDefault(require("./extractSignature"));
|
||||
@ -44,6 +44,8 @@ var _removeTrailingNewLine = _interopRequireDefault(require("./removeTrailingNew
|
||||
|
||||
var _findByteRange = _interopRequireDefault(require("./findByteRange"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
'This string is added so that jest collects coverage for this file'; // eslint-disable-line
|
||||
("This string is added so that jest collects coverage for this file"); // eslint-disable-line
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
@ -17,10 +17,9 @@ PDFAbstractReference - abstract class for PDF reference
|
||||
*/
|
||||
class PDFAbstractReference {
|
||||
toString() {
|
||||
throw new Error('Must be implemented by subclasses');
|
||||
throw new Error("Must be implemented by subclasses");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var _default = PDFAbstractReference;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _abstract_reference = _interopRequireDefault(require("./abstract_reference"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
/*
|
||||
PDFObject by Devon Govett used below.
|
||||
@ -20,26 +22,26 @@ Modifications may have been applied for the purposes of node-signpdf.
|
||||
PDFObject - converts JavaScript types into their corresponding PDF types.
|
||||
By Devon Govett
|
||||
*/
|
||||
const pad = (str, length) => (Array(length + 1).join('0') + str).slice(-length);
|
||||
const pad = (str, length) => (Array(length + 1).join("0") + str).slice(-length);
|
||||
|
||||
const escapableRe = /[\n\r\t\b\f()\\]/g;
|
||||
const escapable = {
|
||||
'\n': '\\n',
|
||||
'\r': '\\r',
|
||||
'\t': '\\t',
|
||||
'\b': '\\b',
|
||||
'\f': '\\f',
|
||||
'\\': '\\\\',
|
||||
'(': '\\(',
|
||||
')': '\\)'
|
||||
"\n": "\\n",
|
||||
"\r": "\\r",
|
||||
"\t": "\\t",
|
||||
"\b": "\\b",
|
||||
"\f": "\\f",
|
||||
"\\": "\\\\",
|
||||
"(": "\\(",
|
||||
")": "\\)",
|
||||
}; // Convert little endian UTF-16 to big endian
|
||||
|
||||
const swapBytes = buff => buff.swap16();
|
||||
const swapBytes = (buff) => buff.swap16();
|
||||
|
||||
class PDFObject {
|
||||
static convert(object, encryptFn = null) {
|
||||
// String literals are converted to the PDF name type
|
||||
if (typeof object === 'string') {
|
||||
if (typeof object === "string") {
|
||||
return `/${object}`; // String objects are converted to PDF strings (UTF-16)
|
||||
}
|
||||
|
||||
@ -55,29 +57,26 @@ class PDFObject {
|
||||
}
|
||||
} // If so, encode it as big endian UTF-16
|
||||
|
||||
|
||||
let stringBuffer;
|
||||
|
||||
if (isUnicode) {
|
||||
stringBuffer = swapBytes(Buffer.from(`\ufeff${string}`, 'utf16le'));
|
||||
stringBuffer = swapBytes(Buffer.from(`\ufeff${string}`, "utf16le"));
|
||||
} else {
|
||||
stringBuffer = Buffer.from(string, 'ascii');
|
||||
stringBuffer = Buffer.from(string, "ascii");
|
||||
} // Encrypt the string when necessary
|
||||
|
||||
|
||||
if (encryptFn) {
|
||||
string = encryptFn(stringBuffer).toString('binary');
|
||||
string = encryptFn(stringBuffer).toString("binary");
|
||||
} else {
|
||||
string = stringBuffer.toString('binary');
|
||||
string = stringBuffer.toString("binary");
|
||||
} // Escape characters as required by the spec
|
||||
|
||||
|
||||
string = string.replace(escapableRe, c => escapable[c]);
|
||||
string = string.replace(escapableRe, (c) => escapable[c]);
|
||||
return `(${string})`; // Buffers are converted to PDF hex strings
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(object)) {
|
||||
return `<${object.toString('hex')}>`;
|
||||
return `<${object.toString("hex")}>`;
|
||||
}
|
||||
|
||||
if (object instanceof _abstract_reference.default) {
|
||||
@ -85,51 +84,54 @@ class PDFObject {
|
||||
}
|
||||
|
||||
if (object instanceof Date) {
|
||||
let string = `D:${pad(object.getUTCFullYear(), 4)}${pad(object.getUTCMonth() + 1, 2)}${pad(object.getUTCDate(), 2)}${pad(object.getUTCHours(), 2)}${pad(object.getUTCMinutes(), 2)}${pad(object.getUTCSeconds(), 2)}Z`; // Encrypt the string when necessary
|
||||
let string = `D:${pad(object.getUTCFullYear(), 4)}${pad(object.getUTCMonth() + 1, 2)}${pad(
|
||||
object.getUTCDate(),
|
||||
2
|
||||
)}${pad(object.getUTCHours(), 2)}${pad(object.getUTCMinutes(), 2)}${pad(object.getUTCSeconds(), 2)}Z`; // Encrypt the string when necessary
|
||||
|
||||
if (encryptFn) {
|
||||
string = encryptFn(Buffer.from(string, 'ascii')).toString('binary'); // Escape characters as required by the spec
|
||||
string = encryptFn(Buffer.from(string, "ascii")).toString("binary"); // Escape characters as required by the spec
|
||||
|
||||
string = string.replace(escapableRe, c => escapable[c]);
|
||||
string = string.replace(escapableRe, (c) => escapable[c]);
|
||||
}
|
||||
|
||||
return `(${string})`;
|
||||
}
|
||||
|
||||
if (Array.isArray(object)) {
|
||||
const items = object.map(e => PDFObject.convert(e, encryptFn)).join(' ');
|
||||
const items = object.map((e) => PDFObject.convert(e, encryptFn)).join(" ");
|
||||
return `[${items}]`;
|
||||
}
|
||||
|
||||
if ({}.toString.call(object) === '[object Object]') {
|
||||
const out = ['<<'];
|
||||
if ({}.toString.call(object) === "[object Object]") {
|
||||
const out = ["<<"];
|
||||
let streamData; // @todo this can probably be refactored into a reduce
|
||||
|
||||
Object.entries(object).forEach(([key, val]) => {
|
||||
let checkedValue = '';
|
||||
let checkedValue = "";
|
||||
|
||||
if (val.toString().indexOf('<<') !== -1) {
|
||||
if (val.toString().indexOf("<<") !== -1) {
|
||||
checkedValue = val;
|
||||
} else {
|
||||
checkedValue = PDFObject.convert(val, encryptFn);
|
||||
}
|
||||
|
||||
if (key === 'stream') {
|
||||
if (key === "stream") {
|
||||
streamData = `${key}\n${val}\nendstream`;
|
||||
} else {
|
||||
out.push(`/${key} ${checkedValue}`);
|
||||
}
|
||||
});
|
||||
out.push('>>');
|
||||
out.push(">>");
|
||||
|
||||
if (streamData) {
|
||||
out.push(streamData);
|
||||
}
|
||||
|
||||
return out.join('\n');
|
||||
return out.join("\n");
|
||||
}
|
||||
|
||||
if (typeof object === 'number') {
|
||||
if (typeof object === "number") {
|
||||
return PDFObject.number(object);
|
||||
}
|
||||
|
||||
@ -143,7 +145,6 @@ class PDFObject {
|
||||
|
||||
throw new Error(`unsupported number: ${n}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.default = PDFObject;
|
||||
exports.default = PDFObject;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
@ -9,7 +9,9 @@ var _const = require("./const");
|
||||
|
||||
var _pdfkitReferenceMock = _interopRequireDefault(require("./pdfkitReferenceMock"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
|
||||
@ -25,18 +27,18 @@ const pdfkitAddPlaceholder = ({
|
||||
pdf,
|
||||
pdfBuffer,
|
||||
reason,
|
||||
contactInfo = 'emailfromp1289@gmail.com',
|
||||
name = 'Name from p12',
|
||||
location = 'Location from p12',
|
||||
contactInfo = "emailfromp1289@gmail.com",
|
||||
name = "Name from p12",
|
||||
location = "Location from p12",
|
||||
signatureLength = _const.DEFAULT_SIGNATURE_LENGTH,
|
||||
byteRangePlaceholder = _const.DEFAULT_BYTE_RANGE_PLACEHOLDER,
|
||||
subFilter = _const.SUBFILTER_ADOBE_PKCS7_DETACHED
|
||||
subFilter = _const.SUBFILTER_ADOBE_PKCS7_DETACHED,
|
||||
}) => {
|
||||
/* eslint-disable no-underscore-dangle,no-param-reassign */
|
||||
// Generate the signature placeholder
|
||||
const signature = pdf.ref({
|
||||
Type: 'Sig',
|
||||
Filter: 'Adobe.PPKLite',
|
||||
Type: "Sig",
|
||||
Filter: "Adobe.PPKLite",
|
||||
SubFilter: subFilter,
|
||||
ByteRange: [0, byteRangePlaceholder, byteRangePlaceholder, byteRangePlaceholder],
|
||||
Contents: Buffer.from(String.fromCharCode(0).repeat(signatureLength)),
|
||||
@ -47,11 +49,10 @@ const pdfkitAddPlaceholder = ({
|
||||
// eslint-disable-line no-new-wrappers
|
||||
Name: new String(name),
|
||||
// eslint-disable-line no-new-wrappers
|
||||
Location: new String(location) // eslint-disable-line no-new-wrappers
|
||||
|
||||
Location: new String(location), // eslint-disable-line no-new-wrappers
|
||||
}); // Check if pdf already contains acroform field
|
||||
|
||||
const acroFormPosition = pdfBuffer.lastIndexOf('/Type /AcroForm');
|
||||
const acroFormPosition = pdfBuffer.lastIndexOf("/Type /AcroForm");
|
||||
const isAcroFormExists = acroFormPosition !== -1;
|
||||
let fieldIds = [];
|
||||
let acroFormId;
|
||||
@ -65,13 +66,13 @@ const pdfkitAddPlaceholder = ({
|
||||
// (generally it's 2 or 3, but I'm giving a big space though)
|
||||
|
||||
const maxAcroFormIdLength = 12;
|
||||
let foundAcroFormId = '';
|
||||
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') {
|
||||
if (acroFormIdString[0] === "\n") {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -80,25 +81,27 @@ const pdfkitAddPlaceholder = ({
|
||||
}
|
||||
|
||||
const pdfSlice = pdfBuffer.slice(acroFormStart);
|
||||
const acroForm = pdfSlice.slice(0, pdfSlice.indexOf('endobj')).toString();
|
||||
const acroForm = pdfSlice.slice(0, pdfSlice.indexOf("endobj")).toString();
|
||||
acroFormId = parseInt(foundAcroFormId);
|
||||
const acroFormFields = acroForm.slice(acroForm.indexOf('/Fields [') + 9, acroForm.indexOf(']'));
|
||||
fieldIds = acroFormFields.split(' ').filter((element, i) => i % 3 === 0).map(fieldId => new _pdfkitReferenceMock.default(fieldId));
|
||||
const acroFormFields = acroForm.slice(acroForm.indexOf("/Fields [") + 9, acroForm.indexOf("]"));
|
||||
fieldIds = acroFormFields
|
||||
.split(" ")
|
||||
.filter((element, i) => i % 3 === 0)
|
||||
.map((fieldId) => new _pdfkitReferenceMock.default(fieldId));
|
||||
}
|
||||
|
||||
const signatureName = 'Signature'; // Generate signature annotation widget
|
||||
const signatureName = "Signature"; // Generate signature annotation widget
|
||||
|
||||
const widget = pdf.ref({
|
||||
Type: 'Annot',
|
||||
Subtype: 'Widget',
|
||||
FT: 'Sig',
|
||||
Type: "Annot",
|
||||
Subtype: "Widget",
|
||||
FT: "Sig",
|
||||
Rect: [0, 0, 0, 0],
|
||||
V: signature,
|
||||
T: new String(signatureName + (fieldIds.length + 1)),
|
||||
// eslint-disable-line no-new-wrappers
|
||||
F: 4,
|
||||
P: pdf.page.dictionary // eslint-disable-line no-underscore-dangle
|
||||
|
||||
P: pdf.page.dictionary, // eslint-disable-line no-underscore-dangle
|
||||
});
|
||||
pdf.page.dictionary.data.Annots = [widget]; // Include the widget in a page
|
||||
|
||||
@ -107,27 +110,30 @@ const pdfkitAddPlaceholder = ({
|
||||
if (!isAcroFormExists) {
|
||||
// Create a form (with the widget) and link in the _root
|
||||
form = pdf.ref({
|
||||
Type: 'AcroForm',
|
||||
Type: "AcroForm",
|
||||
SigFlags: 3,
|
||||
Fields: [...fieldIds, widget]
|
||||
Fields: [...fieldIds, widget],
|
||||
});
|
||||
} else {
|
||||
// Use existing acroform and extend the fields with newly created widgets
|
||||
form = pdf.ref({
|
||||
Type: 'AcroForm',
|
||||
SigFlags: 3,
|
||||
Fields: [...fieldIds, widget]
|
||||
}, acroFormId);
|
||||
form = pdf.ref(
|
||||
{
|
||||
Type: "AcroForm",
|
||||
SigFlags: 3,
|
||||
Fields: [...fieldIds, widget],
|
||||
},
|
||||
acroFormId
|
||||
);
|
||||
}
|
||||
|
||||
pdf._root.data.AcroForm = form;
|
||||
return {
|
||||
signature,
|
||||
form,
|
||||
widget
|
||||
widget,
|
||||
};
|
||||
/* eslint-enable no-underscore-dangle,no-param-reassign */
|
||||
};
|
||||
|
||||
var _default = pdfkitAddPlaceholder;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,20 +1,22 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _abstract_reference = _interopRequireDefault(require("./pdfkit/abstract_reference"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
class PDFKitReferenceMock extends _abstract_reference.default {
|
||||
constructor(index, additionalData = undefined) {
|
||||
super();
|
||||
this.index = index;
|
||||
|
||||
if (typeof additionalData !== 'undefined') {
|
||||
if (typeof additionalData !== "undefined") {
|
||||
Object.assign(this, additionalData);
|
||||
}
|
||||
}
|
||||
@ -22,8 +24,7 @@ class PDFKitReferenceMock extends _abstract_reference.default {
|
||||
toString() {
|
||||
return `${this.index} 0 R`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var _default = PDFKitReferenceMock;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
@ -9,7 +9,9 @@ var _findObject = _interopRequireDefault(require("./findObject"));
|
||||
|
||||
var _getIndexFromRef = _interopRequireDefault(require("./getIndexFromRef"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
const createBufferPageWithAnnotation = (pdf, info, pagesRef, widget) => {
|
||||
const pagesDictionary = (0, _findObject.default)(pdf, info.xref, pagesRef).toString(); // Extend page dictionary with newly created annotations
|
||||
@ -17,16 +19,16 @@ const createBufferPageWithAnnotation = (pdf, info, pagesRef, widget) => {
|
||||
let annotsStart;
|
||||
let annotsEnd;
|
||||
let annots;
|
||||
annotsStart = pagesDictionary.indexOf('/Annots');
|
||||
annotsStart = pagesDictionary.indexOf("/Annots");
|
||||
|
||||
if (annotsStart > -1) {
|
||||
annotsEnd = pagesDictionary.indexOf(']', annotsStart);
|
||||
annotsEnd = pagesDictionary.indexOf("]", annotsStart);
|
||||
annots = pagesDictionary.substr(annotsStart, annotsEnd + 1 - annotsStart);
|
||||
annots = annots.substr(0, annots.length - 1); // remove the trailing ]
|
||||
} else {
|
||||
annotsStart = pagesDictionary.length;
|
||||
annotsEnd = pagesDictionary.length;
|
||||
annots = '/Annots [';
|
||||
annots = "/Annots [";
|
||||
}
|
||||
|
||||
const pagesDictionaryIndex = (0, _getIndexFromRef.default)(info.xref, pagesRef);
|
||||
@ -34,14 +36,19 @@ const createBufferPageWithAnnotation = (pdf, info, pagesRef, widget) => {
|
||||
annots = `${annots} ${widgetValue}]`; // add the trailing ] back
|
||||
|
||||
const preAnnots = pagesDictionary.substr(0, annotsStart);
|
||||
let postAnnots = '';
|
||||
let postAnnots = "";
|
||||
|
||||
if (pagesDictionary.length > annotsEnd) {
|
||||
postAnnots = pagesDictionary.substr(annotsEnd + 1);
|
||||
}
|
||||
|
||||
return Buffer.concat([Buffer.from(`${pagesDictionaryIndex} 0 obj\n`), Buffer.from('<<\n'), Buffer.from(`${preAnnots + annots + postAnnots}\n`), Buffer.from('\n>>\nendobj\n')]);
|
||||
return Buffer.concat([
|
||||
Buffer.from(`${pagesDictionaryIndex} 0 obj\n`),
|
||||
Buffer.from("<<\n"),
|
||||
Buffer.from(`${preAnnots + annots + postAnnots}\n`),
|
||||
Buffer.from("\n>>\nendobj\n"),
|
||||
]);
|
||||
};
|
||||
|
||||
var _default = createBufferPageWithAnnotation;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,18 +1,26 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _getIndexFromRef = _interopRequireDefault(require("./getIndexFromRef"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
const createBufferRootWithAcroform = (pdf, info, form) => {
|
||||
const rootIndex = (0, _getIndexFromRef.default)(info.xref, info.rootRef);
|
||||
return Buffer.concat([Buffer.from(`${rootIndex} 0 obj\n`), Buffer.from('<<\n'), Buffer.from(`${info.root}\n`), Buffer.from(`/AcroForm ${form}`), Buffer.from('\n>>\nendobj\n')]);
|
||||
return Buffer.concat([
|
||||
Buffer.from(`${rootIndex} 0 obj\n`),
|
||||
Buffer.from("<<\n"),
|
||||
Buffer.from(`${info.root}\n`),
|
||||
Buffer.from(`/AcroForm ${form}`),
|
||||
Buffer.from("\n>>\nendobj\n"),
|
||||
]);
|
||||
};
|
||||
|
||||
var _default = createBufferRootWithAcroform;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,21 +1,35 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
const createBufferTrailer = (pdf, info, addedReferences) => {
|
||||
let rows = [];
|
||||
rows[0] = '0000000000 65535 f '; // info.xref.tableRows[0];
|
||||
rows[0] = "0000000000 65535 f "; // info.xref.tableRows[0];
|
||||
|
||||
addedReferences.forEach((offset, index) => {
|
||||
const paddedOffset = `0000000000${offset}`.slice(-10);
|
||||
rows[index + 1] = `${index} 1\n${paddedOffset} 00000 n `;
|
||||
});
|
||||
rows = rows.filter(row => row !== undefined);
|
||||
return Buffer.concat([Buffer.from('xref\n'), Buffer.from(`${info.xref.startingIndex} 1\n`), Buffer.from(rows.join('\n')), Buffer.from('\ntrailer\n'), Buffer.from('<<\n'), Buffer.from(`/Size ${info.xref.maxIndex + 1}\n`), Buffer.from(`/Root ${info.rootRef}\n`), Buffer.from(info.infoRef ? `/Info ${info.infoRef}\n` : ''), Buffer.from(`/Prev ${info.xRefPosition}\n`), Buffer.from('>>\n'), Buffer.from('startxref\n'), Buffer.from(`${pdf.length}\n`), Buffer.from('%%EOF')]);
|
||||
rows = rows.filter((row) => row !== undefined);
|
||||
return Buffer.concat([
|
||||
Buffer.from("xref\n"),
|
||||
Buffer.from(`${info.xref.startingIndex} 1\n`),
|
||||
Buffer.from(rows.join("\n")),
|
||||
Buffer.from("\ntrailer\n"),
|
||||
Buffer.from("<<\n"),
|
||||
Buffer.from(`/Size ${info.xref.maxIndex + 1}\n`),
|
||||
Buffer.from(`/Root ${info.rootRef}\n`),
|
||||
Buffer.from(info.infoRef ? `/Info ${info.infoRef}\n` : ""),
|
||||
Buffer.from(`/Prev ${info.xRefPosition}\n`),
|
||||
Buffer.from(">>\n"),
|
||||
Buffer.from("startxref\n"),
|
||||
Buffer.from(`${pdf.length}\n`),
|
||||
Buffer.from("%%EOF"),
|
||||
]);
|
||||
};
|
||||
|
||||
var _default = createBufferTrailer;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _getIndexFromRef = _interopRequireDefault(require("./getIndexFromRef"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Buffer} pdf
|
||||
@ -18,12 +20,12 @@ const findObject = (pdf, refTable, ref) => {
|
||||
const index = (0, _getIndexFromRef.default)(refTable, ref);
|
||||
const offset = refTable.offsets.get(index);
|
||||
let slice = pdf.slice(offset);
|
||||
slice = slice.slice(0, slice.indexOf('endobj', 'utf8')); // 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('<<', 'utf8') + 2);
|
||||
slice = slice.slice(0, slice.lastIndexOf('>>', 'utf8'));
|
||||
slice = slice.slice(slice.indexOf("<<", "utf8") + 2);
|
||||
slice = slice.slice(0, slice.lastIndexOf(">>", "utf8"));
|
||||
return slice;
|
||||
};
|
||||
|
||||
var _default = findObject;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _SignPdfError = _interopRequireDefault(require("../../SignPdfError"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} refTable
|
||||
@ -15,7 +17,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
||||
* @returns {number}
|
||||
*/
|
||||
const getIndexFromRef = (refTable, ref) => {
|
||||
let [index] = ref.split(' ');
|
||||
let [index] = ref.split(" ");
|
||||
index = parseInt(index);
|
||||
|
||||
if (!refTable.offsets.has(index)) {
|
||||
@ -26,4 +28,4 @@ const getIndexFromRef = (refTable, ref) => {
|
||||
};
|
||||
|
||||
var _default = getIndexFromRef;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = getPageRef;
|
||||
|
||||
@ -9,7 +9,9 @@ var _getPagesDictionaryRef = _interopRequireDefault(require("./getPagesDictionar
|
||||
|
||||
var _findObject = _interopRequireDefault(require("./findObject"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the reference to a page.
|
||||
@ -20,10 +22,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
||||
function getPageRef(pdfBuffer, info) {
|
||||
const pagesRef = (0, _getPagesDictionaryRef.default)(info);
|
||||
const pagesDictionary = (0, _findObject.default)(pdfBuffer, info.xref, pagesRef);
|
||||
const kidsPosition = pagesDictionary.indexOf('/Kids');
|
||||
const kidsStart = pagesDictionary.indexOf('[', kidsPosition) + 1;
|
||||
const kidsEnd = pagesDictionary.indexOf(']', kidsPosition);
|
||||
const kidsPosition = pagesDictionary.indexOf("/Kids");
|
||||
const kidsStart = pagesDictionary.indexOf("[", kidsPosition) + 1;
|
||||
const kidsEnd = pagesDictionary.indexOf("]", kidsPosition);
|
||||
const pages = pagesDictionary.slice(kidsStart, kidsEnd).toString();
|
||||
const split = pages.trim().split(' ', 3);
|
||||
const split = pages.trim().split(" ", 3);
|
||||
return `${split[0]} ${split[1]} ${split[2]}`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = getPagesDictionaryRef;
|
||||
|
||||
var _SignPdfError = _interopRequireDefault(require("../../SignPdfError"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} info As extracted from readRef()
|
||||
@ -17,8 +19,11 @@ function getPagesDictionaryRef(info) {
|
||||
const match = pagesRefRegex.exec(info.root);
|
||||
|
||||
if (match === null) {
|
||||
throw new _SignPdfError.default('Failed to find the pages descriptor. This is probably a problem in node-signpdf.', _SignPdfError.default.TYPE_PARSE);
|
||||
throw new _SignPdfError.default(
|
||||
"Failed to find the pages descriptor. This is probably a problem in node-signpdf.",
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
|
||||
return match[1];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
@ -27,12 +27,14 @@ var _createBufferPageWithAnnotation = _interopRequireDefault(require("./createBu
|
||||
|
||||
var _createBufferTrailer = _interopRequireDefault(require("./createBufferTrailer"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
const isContainBufferRootWithAcroform = pdf => {
|
||||
const isContainBufferRootWithAcroform = (pdf) => {
|
||||
const bufferRootWithAcroformRefRegex = /\/AcroForm\s+(\d+\s\d+\sR)/g;
|
||||
const match = bufferRootWithAcroformRefRegex.exec(pdf.toString());
|
||||
return match != null && match[1] != null && match[1] !== '';
|
||||
return match != null && match[1] != null && match[1] !== "";
|
||||
};
|
||||
/**
|
||||
* Adds a signature placeholder to a PDF Buffer.
|
||||
@ -44,15 +46,14 @@ const isContainBufferRootWithAcroform = pdf => {
|
||||
* not only on a freshly created through PDFKit one.
|
||||
*/
|
||||
|
||||
|
||||
const plainAddPlaceholder = ({
|
||||
pdfBuffer,
|
||||
reason,
|
||||
contactInfo = 'emailfromp1289@gmail.com',
|
||||
name = 'Name from p12',
|
||||
location = 'Location from p12',
|
||||
contactInfo = "emailfromp1289@gmail.com",
|
||||
name = "Name from p12",
|
||||
location = "Location from p12",
|
||||
signatureLength = _const.DEFAULT_SIGNATURE_LENGTH,
|
||||
subFilter = _const.SUBFILTER_ADOBE_PKCS7_DETACHED
|
||||
subFilter = _const.SUBFILTER_ADOBE_PKCS7_DETACHED,
|
||||
}) => {
|
||||
let pdf = (0, _removeTrailingNewLine.default)(pdfBuffer);
|
||||
const info = (0, _readPdf.default)(pdf);
|
||||
@ -65,24 +66,27 @@ const plainAddPlaceholder = ({
|
||||
const index = additionalIndex != null ? additionalIndex : info.xref.maxIndex;
|
||||
addedReferences.set(index, pdf.length + 1); // + 1 new line
|
||||
|
||||
pdf = Buffer.concat([pdf, Buffer.from('\n'), Buffer.from(`${index} 0 obj\n`), Buffer.from(_pdfobject.default.convert(input)), Buffer.from('\nendobj\n')]);
|
||||
pdf = Buffer.concat([
|
||||
pdf,
|
||||
Buffer.from("\n"),
|
||||
Buffer.from(`${index} 0 obj\n`),
|
||||
Buffer.from(_pdfobject.default.convert(input)),
|
||||
Buffer.from("\nendobj\n"),
|
||||
]);
|
||||
return new _pdfkitReferenceMock.default(info.xref.maxIndex);
|
||||
},
|
||||
page: {
|
||||
dictionary: new _pdfkitReferenceMock.default(pageIndex, {
|
||||
data: {
|
||||
Annots: []
|
||||
}
|
||||
})
|
||||
Annots: [],
|
||||
},
|
||||
}),
|
||||
},
|
||||
_root: {
|
||||
data: {}
|
||||
}
|
||||
data: {},
|
||||
},
|
||||
};
|
||||
const {
|
||||
form,
|
||||
widget
|
||||
} = (0, _pdfkitAddPlaceholder.default)({
|
||||
const { form, widget } = (0, _pdfkitAddPlaceholder.default)({
|
||||
pdf: pdfKitMock,
|
||||
pdfBuffer,
|
||||
reason,
|
||||
@ -90,20 +94,32 @@ const plainAddPlaceholder = ({
|
||||
name,
|
||||
location,
|
||||
signatureLength,
|
||||
subFilter
|
||||
subFilter,
|
||||
});
|
||||
|
||||
if (!isContainBufferRootWithAcroform(pdf)) {
|
||||
const rootIndex = (0, _getIndexFromRef.default)(info.xref, info.rootRef);
|
||||
addedReferences.set(rootIndex, pdf.length + 1);
|
||||
pdf = Buffer.concat([pdf, Buffer.from('\n'), (0, _createBufferRootWithAcroform.default)(pdf, info, form)]);
|
||||
pdf = Buffer.concat([
|
||||
pdf,
|
||||
Buffer.from("\n"),
|
||||
(0, _createBufferRootWithAcroform.default)(pdf, info, form),
|
||||
]);
|
||||
}
|
||||
|
||||
addedReferences.set(pageIndex, pdf.length + 1);
|
||||
pdf = Buffer.concat([pdf, Buffer.from('\n'), (0, _createBufferPageWithAnnotation.default)(pdf, info, pageRef, widget)]);
|
||||
pdf = Buffer.concat([pdf, Buffer.from('\n'), (0, _createBufferTrailer.default)(pdf, info, addedReferences)]);
|
||||
pdf = Buffer.concat([
|
||||
pdf,
|
||||
Buffer.from("\n"),
|
||||
(0, _createBufferPageWithAnnotation.default)(pdf, info, pageRef, widget),
|
||||
]);
|
||||
pdf = Buffer.concat([
|
||||
pdf,
|
||||
Buffer.from("\n"),
|
||||
(0, _createBufferTrailer.default)(pdf, info, addedReferences),
|
||||
]);
|
||||
return pdf;
|
||||
};
|
||||
|
||||
var _default = plainAddPlaceholder;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
@ -9,7 +9,9 @@ var _readRefTable = _interopRequireDefault(require("./readRefTable"));
|
||||
|
||||
var _findObject = _interopRequireDefault(require("./findObject"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
const getValue = (trailer, key) => {
|
||||
let index = trailer.indexOf(key);
|
||||
@ -19,13 +21,16 @@ const getValue = (trailer, key) => {
|
||||
}
|
||||
|
||||
const slice = trailer.slice(index);
|
||||
index = slice.indexOf('/', 1);
|
||||
index = slice.indexOf("/", 1);
|
||||
|
||||
if (index === -1) {
|
||||
index = slice.indexOf('>', 1);
|
||||
index = slice.indexOf(">", 1);
|
||||
}
|
||||
|
||||
return slice.slice(key.length + 1, index).toString().trim(); // key + at least one space
|
||||
return slice
|
||||
.slice(key.length + 1, index)
|
||||
.toString()
|
||||
.trim(); // key + at least one space
|
||||
};
|
||||
/**
|
||||
* Simplified parsing of a PDF Buffer.
|
||||
@ -36,18 +41,17 @@ const getValue = (trailer, key) => {
|
||||
* @param {Buffer} pdfBuffer
|
||||
*/
|
||||
|
||||
|
||||
const readPdf = pdfBuffer => {
|
||||
const readPdf = (pdfBuffer) => {
|
||||
// Extract the trailer dictionary.
|
||||
const trailerStart = pdfBuffer.lastIndexOf('trailer'); // The trailer is followed by xref. Then an EOF. EOF's length is 6 characters.
|
||||
const trailerStart = pdfBuffer.lastIndexOf("trailer"); // The trailer is followed by xref. Then an EOF. EOF's length is 6 characters.
|
||||
|
||||
const trailer = pdfBuffer.slice(trailerStart, pdfBuffer.length - 6);
|
||||
let xRefPosition = trailer.slice(trailer.lastIndexOf('startxref') + 10).toString();
|
||||
let xRefPosition = trailer.slice(trailer.lastIndexOf("startxref") + 10).toString();
|
||||
xRefPosition = parseInt(xRefPosition);
|
||||
const refTable = (0, _readRefTable.default)(pdfBuffer);
|
||||
const rootRef = getValue(trailer, '/Root');
|
||||
const rootRef = getValue(trailer, "/Root");
|
||||
const root = (0, _findObject.default)(pdfBuffer, refTable, rootRef).toString();
|
||||
const infoRef = getValue(trailer, '/Info');
|
||||
const infoRef = getValue(trailer, "/Info");
|
||||
return {
|
||||
xref: refTable,
|
||||
rootRef,
|
||||
@ -55,9 +59,9 @@ const readPdf = pdfBuffer => {
|
||||
infoRef,
|
||||
trailerStart,
|
||||
previousXrefs: [],
|
||||
xRefPosition
|
||||
xRefPosition,
|
||||
};
|
||||
};
|
||||
|
||||
var _default = readPdf;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.getXref = exports.getLastTrailerPosition = exports.getFullXrefTable = exports.default = void 0;
|
||||
|
||||
@ -9,12 +9,14 @@ var _SignPdfError = _interopRequireDefault(require("../../SignPdfError"));
|
||||
|
||||
var _xrefToRefMap = _interopRequireDefault(require("./xrefToRefMap"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
const getLastTrailerPosition = pdf => {
|
||||
const trailerStart = pdf.lastIndexOf(Buffer.from('trailer', 'utf8'));
|
||||
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();
|
||||
const xRefPosition = trailer.slice(trailer.lastIndexOf(Buffer.from("startxref", "utf8")) + 10).toString();
|
||||
return parseInt(xRefPosition);
|
||||
};
|
||||
|
||||
@ -23,47 +25,56 @@ exports.getLastTrailerPosition = getLastTrailerPosition;
|
||||
const getXref = (pdf, position) => {
|
||||
let refTable = pdf.slice(position); // slice starting from where xref starts
|
||||
|
||||
const realPosition = refTable.indexOf(Buffer.from('xref', 'utf8'));
|
||||
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);
|
||||
throw new _SignPdfError.default(
|
||||
`Could not find xref anywhere at or after ${position}.`,
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
|
||||
if (realPosition > 0) {
|
||||
const prefix = refTable.slice(0, realPosition);
|
||||
|
||||
if (prefix.toString().replace(/\s*/g, '') !== '') {
|
||||
throw new _SignPdfError.default(`Expected xref at ${position} but found other content.`, _SignPdfError.default.TYPE_PARSE);
|
||||
if (prefix.toString().replace(/\s*/g, "") !== "") {
|
||||
throw new _SignPdfError.default(
|
||||
`Expected xref at ${position} but found other content.`,
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const nextEofPosition = refTable.indexOf(Buffer.from('%%EOF', 'utf8'));
|
||||
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);
|
||||
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
|
||||
refTable = refTable.slice(refTable.indexOf("\n") + 1); // move after the next new line
|
||||
// extract the size
|
||||
|
||||
let size = refTable.toString().split('/Size')[1];
|
||||
let size = refTable.toString().split("/Size")[1];
|
||||
|
||||
if (!size) {
|
||||
throw new _SignPdfError.default('Size not found in xref table.', _SignPdfError.default.TYPE_PARSE);
|
||||
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);
|
||||
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;
|
||||
const [objects, infos] = refTable.toString().split("trailer");
|
||||
const isContainingPrev = infos.split("/Prev")[1] != null;
|
||||
let prev;
|
||||
|
||||
if (isContainingPrev) {
|
||||
@ -77,13 +88,13 @@ const getXref = (pdf, position) => {
|
||||
return {
|
||||
size,
|
||||
prev,
|
||||
xRefContent
|
||||
xRefContent,
|
||||
};
|
||||
};
|
||||
|
||||
exports.getXref = getXref;
|
||||
|
||||
const getFullXrefTable = pdf => {
|
||||
const getFullXrefTable = (pdf) => {
|
||||
const lastTrailerPosition = getLastTrailerPosition(pdf);
|
||||
const lastXrefTable = getXref(pdf, lastTrailerPosition);
|
||||
|
||||
@ -101,19 +112,18 @@ const getFullXrefTable = pdf => {
|
||||
* @returns {object}
|
||||
*/
|
||||
|
||||
|
||||
exports.getFullXrefTable = getFullXrefTable;
|
||||
|
||||
const readRefTable = pdf => {
|
||||
const readRefTable = (pdf) => {
|
||||
const fullXrefTable = getFullXrefTable(pdf);
|
||||
const startingIndex = 0;
|
||||
const maxIndex = Math.max(...fullXrefTable.keys());
|
||||
return {
|
||||
startingIndex,
|
||||
maxIndex,
|
||||
offsets: fullXrefTable
|
||||
offsets: fullXrefTable,
|
||||
};
|
||||
};
|
||||
|
||||
var _default = readRefTable;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,21 +1,23 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _SignPdfError = _interopRequireDefault(require("../../SignPdfError"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
const xrefToRefMap = xrefString => {
|
||||
const lines = xrefString.split('\n').filter(l => l !== '');
|
||||
const xrefToRefMap = (xrefString) => {
|
||||
const lines = xrefString.split("\n").filter((l) => l !== "");
|
||||
let index = 0;
|
||||
let expectedLines = 0;
|
||||
const xref = new Map();
|
||||
lines.forEach(line => {
|
||||
const split = line.split(' ');
|
||||
lines.forEach((line) => {
|
||||
const split = line.split(" ");
|
||||
|
||||
if (split.length === 2) {
|
||||
index = parseInt(split[0]);
|
||||
@ -24,23 +26,29 @@ const xrefToRefMap = xrefString => {
|
||||
}
|
||||
|
||||
if (expectedLines <= 0) {
|
||||
throw new _SignPdfError.default('Too many lines in xref table.', _SignPdfError.default.TYPE_PARSE);
|
||||
throw new _SignPdfError.default("Too many lines in xref table.", _SignPdfError.default.TYPE_PARSE);
|
||||
}
|
||||
|
||||
expectedLines -= 1;
|
||||
const [offset,, inUse] = split;
|
||||
const [offset, , inUse] = split;
|
||||
|
||||
if (inUse.trim() === 'f') {
|
||||
if (inUse.trim() === "f") {
|
||||
index += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (inUse.trim() !== 'n') {
|
||||
throw new _SignPdfError.default(`Unknown in-use flag "${inUse}". Expected "n" or "f".`, _SignPdfError.default.TYPE_PARSE);
|
||||
if (inUse.trim() !== "n") {
|
||||
throw new _SignPdfError.default(
|
||||
`Unknown in-use flag "${inUse}". Expected "n" or "f".`,
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
|
||||
if (!/^\d+$/.test(offset.trim())) {
|
||||
throw new _SignPdfError.default(`Expected integer offset. Got "${offset}".`, _SignPdfError.default.TYPE_PARSE);
|
||||
throw new _SignPdfError.default(
|
||||
`Expected integer offset. Got "${offset}".`,
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
|
||||
const storeOffset = parseInt(offset.trim());
|
||||
@ -51,4 +59,4 @@ const xrefToRefMap = xrefString => {
|
||||
};
|
||||
|
||||
var _default = xrefToRefMap;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _SignPdfError = _interopRequireDefault(require("../SignPdfError"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
const sliceLastChar = (pdf, character) => {
|
||||
const lastChar = pdf.slice(pdf.length - 1).toString();
|
||||
@ -26,23 +28,25 @@ const sliceLastChar = (pdf, character) => {
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
|
||||
const removeTrailingNewLine = pdf => {
|
||||
const removeTrailingNewLine = (pdf) => {
|
||||
if (!(pdf instanceof Buffer)) {
|
||||
throw new _SignPdfError.default('PDF expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
|
||||
throw new _SignPdfError.default("PDF expected as Buffer.", _SignPdfError.default.TYPE_INPUT);
|
||||
}
|
||||
|
||||
let output = pdf;
|
||||
output = sliceLastChar(output, '\n');
|
||||
output = sliceLastChar(output, '\r');
|
||||
output = sliceLastChar(output, "\n");
|
||||
output = sliceLastChar(output, "\r");
|
||||
const lastLine = output.slice(output.length - 6).toString();
|
||||
|
||||
if (lastLine !== '\n%%EOF') {
|
||||
throw new _SignPdfError.default('A PDF file must end with an EOF line.', _SignPdfError.default.TYPE_PARSE);
|
||||
if (lastLine !== "\n%%EOF") {
|
||||
throw new _SignPdfError.default(
|
||||
"A PDF file must end with an EOF line.",
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
var _default = removeTrailingNewLine;
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
120
packages/signing/node-signpdf/dist/signpdf.js
vendored
120
packages/signing/node-signpdf/dist/signpdf.js
vendored
@ -1,18 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
value: true,
|
||||
});
|
||||
var _exportNames = {
|
||||
SignPdf: true,
|
||||
SignPdfError: true
|
||||
SignPdfError: true,
|
||||
};
|
||||
exports.SignPdf = void 0;
|
||||
Object.defineProperty(exports, "SignPdfError", {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _SignPdfError.default;
|
||||
}
|
||||
},
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
@ -30,7 +30,7 @@ Object.keys(_helpers).forEach(function (key) {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _helpers[key];
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@ -44,11 +44,13 @@ Object.keys(_const).forEach(function (key) {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _const[key];
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : { default: obj };
|
||||
}
|
||||
|
||||
class SignPdf {
|
||||
constructor() {
|
||||
@ -59,77 +61,81 @@ class SignPdf {
|
||||
sign(pdfBuffer, p12Buffer, additionalOptions = {}) {
|
||||
const options = {
|
||||
asn1StrictParsing: false,
|
||||
passphrase: '',
|
||||
...additionalOptions
|
||||
passphrase: "",
|
||||
...additionalOptions,
|
||||
};
|
||||
|
||||
if (!(pdfBuffer instanceof Buffer)) {
|
||||
throw new _SignPdfError.default('PDF expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
|
||||
throw new _SignPdfError.default("PDF expected as Buffer.", _SignPdfError.default.TYPE_INPUT);
|
||||
}
|
||||
|
||||
if (!(p12Buffer instanceof Buffer)) {
|
||||
throw new _SignPdfError.default('p12 certificate expected as Buffer.', _SignPdfError.default.TYPE_INPUT);
|
||||
throw new _SignPdfError.default(
|
||||
"p12 certificate expected as Buffer.",
|
||||
_SignPdfError.default.TYPE_INPUT
|
||||
);
|
||||
}
|
||||
|
||||
let pdf = (0, _helpers.removeTrailingNewLine)(pdfBuffer); // Find the ByteRange placeholder.
|
||||
|
||||
const {
|
||||
byteRangePlaceholder
|
||||
} = (0, _helpers.findByteRange)(pdf);
|
||||
const { byteRangePlaceholder } = (0, _helpers.findByteRange)(pdf);
|
||||
|
||||
if (!byteRangePlaceholder) {
|
||||
throw new _SignPdfError.default(`Could not find empty ByteRange placeholder: ${byteRangePlaceholder}`, _SignPdfError.default.TYPE_PARSE);
|
||||
throw new _SignPdfError.default(
|
||||
`Could not find empty ByteRange placeholder: ${byteRangePlaceholder}`,
|
||||
_SignPdfError.default.TYPE_PARSE
|
||||
);
|
||||
}
|
||||
|
||||
const byteRangePos = pdf.indexOf(byteRangePlaceholder); // Calculate the actual ByteRange that needs to replace the placeholder.
|
||||
|
||||
const byteRangeEnd = byteRangePos + byteRangePlaceholder.length;
|
||||
const contentsTagPos = pdf.indexOf('/Contents ', byteRangeEnd);
|
||||
const placeholderPos = pdf.indexOf('<', contentsTagPos);
|
||||
const placeholderEnd = pdf.indexOf('>', placeholderPos);
|
||||
const contentsTagPos = pdf.indexOf("/Contents ", byteRangeEnd);
|
||||
const placeholderPos = pdf.indexOf("<", contentsTagPos);
|
||||
const placeholderEnd = pdf.indexOf(">", placeholderPos);
|
||||
const placeholderLengthWithBrackets = placeholderEnd + 1 - placeholderPos;
|
||||
const placeholderLength = placeholderLengthWithBrackets - 2;
|
||||
const byteRange = [0, 0, 0, 0];
|
||||
byteRange[1] = placeholderPos;
|
||||
byteRange[2] = byteRange[1] + placeholderLengthWithBrackets;
|
||||
byteRange[3] = pdf.length - byteRange[2];
|
||||
let actualByteRange = `/ByteRange [${byteRange.join(' ')}]`;
|
||||
actualByteRange += ' '.repeat(byteRangePlaceholder.length - actualByteRange.length); // Replace the /ByteRange placeholder with the actual ByteRange
|
||||
let actualByteRange = `/ByteRange [${byteRange.join(" ")}]`;
|
||||
actualByteRange += " ".repeat(byteRangePlaceholder.length - actualByteRange.length); // Replace the /ByteRange placeholder with the actual ByteRange
|
||||
|
||||
pdf = Buffer.concat([pdf.slice(0, byteRangePos), Buffer.from(actualByteRange), pdf.slice(byteRangeEnd)]); // Remove the placeholder signature
|
||||
|
||||
pdf = Buffer.concat([pdf.slice(0, byteRange[1]), pdf.slice(byteRange[2], byteRange[2] + byteRange[3])]); // Convert Buffer P12 to a forge implementation.
|
||||
|
||||
const forgeCert = _nodeForge.default.util.createBuffer(p12Buffer.toString('binary'));
|
||||
const forgeCert = _nodeForge.default.util.createBuffer(p12Buffer.toString("binary"));
|
||||
|
||||
const p12Asn1 = _nodeForge.default.asn1.fromDer(forgeCert);
|
||||
|
||||
const p12 = _nodeForge.default.pkcs12.pkcs12FromAsn1(p12Asn1, options.asn1StrictParsing, options.passphrase); // Extract safe bags by type.
|
||||
const p12 = _nodeForge.default.pkcs12.pkcs12FromAsn1(
|
||||
p12Asn1,
|
||||
options.asn1StrictParsing,
|
||||
options.passphrase
|
||||
); // Extract safe bags by type.
|
||||
// We will need all the certificates and the private key.
|
||||
|
||||
|
||||
const certBags = p12.getBags({
|
||||
bagType: _nodeForge.default.pki.oids.certBag
|
||||
bagType: _nodeForge.default.pki.oids.certBag,
|
||||
})[_nodeForge.default.pki.oids.certBag];
|
||||
|
||||
const keyBags = p12.getBags({
|
||||
bagType: _nodeForge.default.pki.oids.pkcs8ShroudedKeyBag
|
||||
bagType: _nodeForge.default.pki.oids.pkcs8ShroudedKeyBag,
|
||||
})[_nodeForge.default.pki.oids.pkcs8ShroudedKeyBag];
|
||||
|
||||
const privateKey = keyBags[0].key; // Here comes the actual PKCS#7 signing.
|
||||
|
||||
const p7 = _nodeForge.default.pkcs7.createSignedData(); // Start off by setting the content.
|
||||
|
||||
|
||||
p7.content = _nodeForge.default.util.createBuffer(pdf.toString('binary')); // Then add all the certificates (-cacerts & -clcerts)
|
||||
p7.content = _nodeForge.default.util.createBuffer(pdf.toString("binary")); // Then add all the certificates (-cacerts & -clcerts)
|
||||
// Keep track of the last found client certificate.
|
||||
// This will be the public key that will be bundled in the signature.
|
||||
|
||||
let certificate;
|
||||
Object.keys(certBags).forEach(i => {
|
||||
const {
|
||||
publicKey
|
||||
} = certBags[i].cert;
|
||||
Object.keys(certBags).forEach((i) => {
|
||||
const { publicKey } = certBags[i].cert;
|
||||
p7.addCertificate(certBags[i].cert); // Try to find the certificate that matches the private key.
|
||||
|
||||
if (privateKey.n.compareTo(publicKey.n) === 0 && privateKey.e.compareTo(publicKey.e) === 0) {
|
||||
@ -137,57 +143,65 @@ class SignPdf {
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof certificate === 'undefined') {
|
||||
throw new _SignPdfError.default('Failed to find a certificate that matches the private key.', _SignPdfError.default.TYPE_INPUT);
|
||||
if (typeof certificate === "undefined") {
|
||||
throw new _SignPdfError.default(
|
||||
"Failed to find a certificate that matches the private key.",
|
||||
_SignPdfError.default.TYPE_INPUT
|
||||
);
|
||||
} // Add a sha256 signer. That's what Adobe.PPKLite adbe.pkcs7.detached expects.
|
||||
|
||||
|
||||
p7.addSigner({
|
||||
key: privateKey,
|
||||
certificate,
|
||||
digestAlgorithm: _nodeForge.default.pki.oids.sha256,
|
||||
authenticatedAttributes: [{
|
||||
type: _nodeForge.default.pki.oids.contentType,
|
||||
value: _nodeForge.default.pki.oids.data
|
||||
}, {
|
||||
type: _nodeForge.default.pki.oids.signingTime,
|
||||
// value can also be auto-populated at signing time
|
||||
// We may also support passing this as an option to sign().
|
||||
// Would be useful to match the creation time of the document for example.
|
||||
value: new Date()
|
||||
}, {
|
||||
type: _nodeForge.default.pki.oids.messageDigest // value will be auto-populated at signing time
|
||||
|
||||
}]
|
||||
authenticatedAttributes: [
|
||||
{
|
||||
type: _nodeForge.default.pki.oids.contentType,
|
||||
value: _nodeForge.default.pki.oids.data,
|
||||
},
|
||||
{
|
||||
type: _nodeForge.default.pki.oids.signingTime,
|
||||
// value can also be auto-populated at signing time
|
||||
// We may also support passing this as an option to sign().
|
||||
// Would be useful to match the creation time of the document for example.
|
||||
value: new Date(),
|
||||
},
|
||||
{
|
||||
type: _nodeForge.default.pki.oids.messageDigest, // value will be auto-populated at signing time
|
||||
},
|
||||
],
|
||||
}); // Sign in detached mode.
|
||||
|
||||
p7.sign({
|
||||
detached: true
|
||||
detached: true,
|
||||
}); // Check if the PDF has a good enough placeholder to fit the signature.
|
||||
|
||||
const raw = _nodeForge.default.asn1.toDer(p7.toAsn1()).getBytes(); // placeholderLength represents the length of the HEXified symbols but we're
|
||||
// checking the actual lengths.
|
||||
|
||||
|
||||
if (raw.length * 2 > placeholderLength) {
|
||||
throw new _SignPdfError.default(`Signature exceeds placeholder length: ${raw.length * 2} > ${placeholderLength}`, _SignPdfError.default.TYPE_INPUT);
|
||||
throw new _SignPdfError.default(
|
||||
`Signature exceeds placeholder length: ${raw.length * 2} > ${placeholderLength}`,
|
||||
_SignPdfError.default.TYPE_INPUT
|
||||
);
|
||||
}
|
||||
|
||||
let signature = Buffer.from(raw, 'binary').toString('hex'); // Store the HEXified signature. At least useful in tests.
|
||||
let signature = Buffer.from(raw, "binary").toString("hex"); // Store the HEXified signature. At least useful in tests.
|
||||
|
||||
this.lastSignature = signature; // Pad the signature with zeroes so the it is the same length as the placeholder
|
||||
|
||||
signature += Buffer.from(String.fromCharCode(0).repeat(placeholderLength / 2 - raw.length)).toString('hex'); // Place it in the document.
|
||||
signature += Buffer.from(String.fromCharCode(0).repeat(placeholderLength / 2 - raw.length)).toString(
|
||||
"hex"
|
||||
); // Place it in the document.
|
||||
|
||||
pdf = Buffer.concat([pdf.slice(0, byteRange[1]), Buffer.from(`<${signature}>`), pdf.slice(byteRange[1])]); // Magic. Done.
|
||||
|
||||
return pdf;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.SignPdf = SignPdf;
|
||||
|
||||
var _default = new SignPdf();
|
||||
|
||||
exports.default = _default;
|
||||
exports.default = _default;
|
||||
|
||||
Reference in New Issue
Block a user