Merge pull request #759 from OpenSignLabs/feat_resendmail

This commit is contained in:
Amol
2024-05-21 15:18:10 +05:30
committed by GitHub
21 changed files with 103 additions and 256 deletions
+103 -92
View File
@@ -1,13 +1,16 @@
import SignPDF from './SignPDF.min.cjs';
import fs from 'node:fs';
import axios from 'axios';
import { pdflibAddPlaceholder } from './customSignPdf/pdflibplaceholder.min.js';
import { SignPdf } from '@signpdf/signpdf';
import { P12Signer } from '@signpdf/signer-p12';
import { pdflibAddPlaceholder } from '@signpdf/placeholder-pdf-lib';
import { PDFDocument } from 'pdf-lib';
import { replaceMailVaribles, saveFileUsage } from '../../../Utils.js';
import GenerateCertificate from './GenerateCertificate.js';
const serverUrl = process.env.SERVER_URL,
APPID = process.env.APP_ID,
masterKEY = process.env.MASTER_KEY;
masterKEY = process.env.MASTER_KEY,
eSignName = 'opensign',
eSigncontact = 'hello@opensignlabs.com';
async function uploadFile(e, t) {
try {
var a = fs.readFileSync(t),
@@ -18,23 +21,23 @@ async function uploadFile(e, t) {
console.log('Err ', e), fs.unlinkSync(t);
}
}
async function updateDoc(a, r, i, s, o, n, l) {
async function updateDoc(a, r, i, n, s, o, l) {
try {
var c,
d,
p = {
UserPtr: { __type: 'Pointer', className: n, objectId: i },
UserPtr: { __type: 'Pointer', className: o, objectId: i },
SignedUrl: r,
Activity: 'Signed',
ipAddress: s,
ipAddress: n,
SignedOn: new Date(),
Signature: l,
};
let e;
var m = (e =
o.AuditTrail && 0 < o.AuditTrail.length
s.AuditTrail && 0 < s.AuditTrail.length
? (-1 !==
(d = (c = JSON.parse(JSON.stringify(o.AuditTrail))).findIndex(
(d = (c = JSON.parse(JSON.stringify(s.AuditTrail))).findIndex(
e => e.UserPtr.objectId === i && 'Created' !== e.Activity
))
? (c[d] = { ...c[d], ...p })
@@ -42,7 +45,7 @@ async function updateDoc(a, r, i, s, o, n, l) {
c)
: [p]).filter(e => 'Signed' === e.Activity);
let t = !1;
!((o.Signers && 0 < o.Signers.length && m.length !== o.Signers.length) || !(t = !0));
!((s.Signers && 0 < s.Signers.length && m.length !== s.Signers.length) || !(t = !0));
var g = { SignedUrl: r, AuditTrail: e, IsCompleted: t };
await axios.put(serverUrl + '/classes/contracts_Document/' + a, g, {
headers: {
@@ -61,9 +64,9 @@ async function sendCompletedMail(e) {
a = e.doc,
r = e.doc.ExtUserPtr,
i = a.Name,
s = r.Email;
let o = `Document "${i}" has been signed by all parties`,
n =
n = r.Email;
let s = `Document "${i}" has been signed by all parties`,
o =
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <div style='background-color:#f5f5f5;padding:20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'> <div><img src=https://qikinnovation.ams3.digitaloceanspaces.com/logo.png height='50' style='padding:20px'/> </div><div style='padding:2px;font-family:system-ui; background-color: #47a3ad;'> <p style='font-size:20px;font-weight:400;color:white;padding-left:20px',> Document signed successfully</p></div><div><p style='padding:20px;font-family:system-ui;font-size:14px'>All parties have successfully signed the document " +
`<b>"${i}"</b>` +
'. Kindly download the document from the attachment.</p></div> </div><div><p>This is an automated email from OpenSign™. For any queries regarding this email, please contact the sender ' +
@@ -80,8 +83,8 @@ async function sendCompletedMail(e) {
g.equalTo('UserId', { __type: 'Pointer', className: '_User', objectId: r.UserId.objectId });
const f = await g.first();
f &&
((l = JSON.parse(JSON.stringify(f)))?.CompletionSubject && (o = l?.CompletionSubject),
l?.CompletionBody && (n = l?.CompletionBody),
((l = JSON.parse(JSON.stringify(f)))?.CompletionSubject && (s = l?.CompletionSubject),
l?.CompletionBody && (o = l?.CompletionBody),
(c = a.ExpiryDate.iso),
(d = new Date(c).toLocaleDateString('en-US', {
day: 'numeric',
@@ -99,9 +102,9 @@ async function sendCompletedMail(e) {
expiry_date: d,
company_name: r.Company,
}),
(m = replaceMailVaribles(o, n, p)),
(o = m.subject),
(n = m.body));
(m = replaceMailVaribles(s, o, p)),
(s = m.subject),
(o = m.body));
} catch (e) {
console.log('error in fetch tenant in signpdf', e.message);
}
@@ -109,10 +112,10 @@ async function sendCompletedMail(e) {
extUserId: r.objectId,
url: t,
from: 'OpenSign™',
recipient: s,
subject: o,
recipient: n,
subject: s,
pdfName: i,
html: n,
html: o,
mailProvider: e.mailProvider,
};
await axios.post(serverUrl + '/functions/sendmailv3', g, {
@@ -124,8 +127,8 @@ async function sendCompletedMail(e) {
});
}
async function sendDoctoWebhook(a, e, t, r, i) {
let s = [];
(s = r
let n = [];
(n = r
? { name: r?.Name, email: r?.Email, phone: r?.Phone }
: a?.Signers?.map(e => ({ name: e.Name, email: e.Email, phone: e.Phone })) || [
{ name: a?.ExtUserPtr?.Name, email: a?.ExtUserPtr?.Email, phone: a?.ExtUserPtr?.Phone },
@@ -133,8 +136,8 @@ async function sendDoctoWebhook(a, e, t, r, i) {
a.ExtUserPtr?.Webhook &&
((r =
'signed' === t
? { signer: s, signedAt: new Date() }
: { signers: s, completedAt: new Date() }),
? { signer: n, signedAt: new Date() }
: { signers: n, completedAt: new Date() }),
(t = {
event: t,
objectId: a?.objectId,
@@ -178,24 +181,27 @@ async function sendDoctoWebhook(a, e, t, r, i) {
}
}));
}
const sendMailsaveCertifcate = async (e, t, a, r, i, s) => {
var o = await GenerateCertificate(e),
o = await PDFDocument.load(o),
o =
const sendMailsaveCertifcate = async (e, t, a, r, i, n) => {
var s = await GenerateCertificate(e),
s = await PDFDocument.load(s),
t = new P12Signer(t, { passphrase: process.env.PASS_PHRASE || null }),
s =
(pdflibAddPlaceholder({
pdfDoc: o,
pdfDoc: s,
reason: 'Digitally signed by OpenSign.',
location: 'n/a',
name: eSignName,
contactInfo: eSigncontact,
signatureLength: 15e3,
}),
await o.save()),
o = Buffer.from(o),
t = await new SignPDF(o, t).signPDF(),
await s.save()),
s = Buffer.from(s),
t = await new SignPdf().sign(s, t),
t =
(fs.writeFileSync('./exports/certificate.pdf', t),
await uploadFile('certificate.pdf', './exports/certificate.pdf')),
n = { CertificateUrl: t.imageUrl };
await axios.put(serverUrl + '/classes/contracts_Document/' + e.objectId, n, {
o = { CertificateUrl: t.imageUrl };
await axios.put(serverUrl + '/classes/contracts_Document/' + e.objectId, o, {
headers: {
'Content-Type': 'application/json',
'X-Parse-Application-Id': APPID,
@@ -205,20 +211,20 @@ const sendMailsaveCertifcate = async (e, t, a, r, i, s) => {
e.IsSendMail && !1 === e.IsSendMail
? console.log("don't send mail")
: sendCompletedMail({ url: a, isCustomMail: r, doc: e, mailProvider: i }),
saveFileUsage(o.length, t.imageUrl, s),
saveFileUsage(s.length, t.imageUrl, n),
sendDoctoWebhook(e, a, 'completed', '', t.imageUrl);
};
async function PDF(o) {
async function PDF(s) {
try {
if (!o?.user)
if (!s?.user)
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'User is not authenticated.');
{
var n = o?.user?.toJSON(),
e = o.params.docId;
const F = o.params.userId;
var l = o.params.isCustomCompletionMail || !1,
c = o.params.mailProvider || '',
d = o.params.signature || '',
var o = s?.user?.toJSON(),
e = s.params.docId;
const C = s.params.userId;
var l = s.params.isCustomCompletionMail || !1,
c = s.params.mailProvider || '',
d = s.params.signature || '',
t = new Parse.Query('contracts_Document'),
a =
(t.include('ExtUserPtr,Signers'),
@@ -227,95 +233,100 @@ async function PDF(o) {
if (!a) throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Document not found.');
var r,
p = a?.toJSON();
let i, s;
F
? ((r = p.Signers.find(e => e.objectId === F)),
let i, n;
C
? ((r = p.Signers.find(e => e.objectId === C)),
console.log('_contractUser ', r),
r && ((i = r), (s = 'contracts_Contactbook')))
: ((s = 'contracts_Users'), (i = p.ExtUserPtr));
r && ((i = r), (n = 'contracts_Contactbook')))
: ((n = 'contracts_Users'), (i = p.ExtUserPtr));
var m,
g = i.Name,
f = i.Email;
if (!o.params.pdfFile) throw (((m = new Error('Pdf file not present!')).code = 400), m);
if (!s.params.pdfFile) throw (((m = new Error('Pdf file not present!')).code = 400), m);
{
let e = Buffer.from(o.params.pdfFile, 'base64');
let e = Buffer.from(s.params.pdfFile, 'base64');
var u = process.env.PFX_BASE64,
h = Buffer.from(u, 'base64'),
y = {
UserPtr: { __type: 'Pointer', className: s, objectId: i.objectId },
y = new P12Signer(h, { passphrase: process.env.PASS_PHRASE || null }),
P = {
UserPtr: { __type: 'Pointer', className: n, objectId: i.objectId },
SignedUrl: '',
Activity: 'Signed',
ipAddress: o.headers['x-real-ip'],
ipAddress: s.headers['x-real-ip'],
};
let t;
var P = (t = p.AuditTrail && 0 < p.AuditTrail.length ? [...p.AuditTrail, y] : [y]).filter(
var v = (t = p.AuditTrail && 0 < p.AuditTrail.length ? [...p.AuditTrail, P] : [P]).filter(
e => 'Signed' === e.Activity
);
let a = !1;
!((p.Signers && 0 < p.Signers.length && P.length !== p.Signers.length) || !(a = !0));
var v,
!((p.Signers && 0 < p.Signers.length && v.length !== p.Signers.length) || !(a = !0));
var S,
b,
S,
w,
U,
D,
I = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`,
_ = './exports/' + I;
I,
_,
E = `exported_file_${Math.floor(5e3 * Math.random())}.pdf`,
D = './exports/' + E;
let r = e.length;
r = (
a
? ((v = p.Signers?.map(e => e.Name + ' <' + e.Email + '>')),
? ((S = p.Signers?.map(e => e.Name + ' <' + e.Email + '>')),
(e =
v && 0 < v.length
S && 0 < S.length
? ((b = await PDFDocument.load(e)),
pdflibAddPlaceholder({
pdfDoc: b,
reason: 'Digitally signed by OpenSign for ' + v?.join(', '),
reason: 'Digitally signed by OpenSign for ' + S?.join(', '),
location: 'n/a',
name: eSignName,
contactInfo: eSigncontact,
signatureLength: 15e3,
}),
(S = await b.save()),
Buffer.from(S))
: ((w = await PDFDocument.load(e)),
(w = await b.save()),
Buffer.from(w))
: ((U = await PDFDocument.load(e)),
pdflibAddPlaceholder({
pdfDoc: w,
pdfDoc: U,
reason: 'Digitally signed by OpenSign for ' + g + ' <' + f + '>',
location: 'n/a',
name: eSignName,
contactInfo: eSigncontact,
signatureLength: 15e3,
}),
(U = await w.save()),
Buffer.from(U))),
(D = await new SignPDF(e, h).signPDF()),
fs.writeFileSync(_, D),
D)
: (fs.writeFileSync(_, e), e)
(I = await U.save()),
Buffer.from(I))),
(_ = await new SignPdf().sign(e, y)),
fs.writeFileSync(D, _),
_)
: (fs.writeFileSync(D, e), e)
).length;
var E = await uploadFile(I, _);
if (E && E.imageUrl) {
var A = await uploadFile(E, D);
if (A && A.imageUrl) {
var x,
A,
j = await updateDoc(
o.params.docId,
E.imageUrl,
j,
N = await updateDoc(
s.params.docId,
A.imageUrl,
i.objectId,
o.headers['x-real-ip'],
s.headers['x-real-ip'],
p,
s,
n,
d
);
if (
(sendDoctoWebhook(p, E.imageUrl, 'signed', i),
saveFileUsage(r, E.imageUrl, n.objectId),
j &&
j.isCompleted &&
((x = { ...p, AuditTrail: j.AuditTrail }),
sendMailsaveCertifcate(x, h, E.imageUrl, l, c, n.objectId)),
fs.unlinkSync(_),
console.log('New Signed PDF created called: ' + _),
'success' === j.message)
(sendDoctoWebhook(p, A.imageUrl, 'signed', i),
saveFileUsage(r, A.imageUrl, o.objectId),
N &&
N.isCompleted &&
((x = { ...p, AuditTrail: N.AuditTrail }),
sendMailsaveCertifcate(x, h, A.imageUrl, l, c, o.objectId)),
fs.unlinkSync(D),
console.log('New Signed PDF created called: ' + D),
'success' === N.message)
)
return { status: 'success', data: E.imageUrl };
throw (((A = new Error('Please provide required parameters!')).code = 400), A);
return { status: 'success', data: A.imageUrl };
throw (((j = new Error('Please provide required parameters!')).code = 400), j);
}
}
}
@@ -1 +0,0 @@
const signer=require("node-signpdf").default;class SignPDF{constructor(e,t){this.pdfDoc=e,this.certificate=t}async signPDF(){return signer.sign(this.pdfDoc,this.certificate, process.env.PASS_PHRASE ? {passphrase : process.env.PASS_PHRASE}: null)}static unit8ToBuffer(e){var t=Buffer.alloc(e.byteLength),r=new Uint8Array(e);for(let e=0;e<t.length;++e)t[e]=r[e];return t}}module.exports=SignPDF;
@@ -1 +0,0 @@
class PDFAbstractReference{toString(){throw new Error("Must be implemented by subclasses")}}export default PDFAbstractReference;
@@ -1 +0,0 @@
import PDFAbstractReference from"./PDFAbstractReference.min.js";class PDFKitReferenceMock extends PDFAbstractReference{constructor(e,t=void 0){super(),this.index=e,void 0!==t&&Object.assign(this,t)}toString(){return this.index+" 0 R"}}export default PDFKitReferenceMock;
@@ -1,20 +0,0 @@
const ERROR_TYPE_UNKNOWN = 1,
ERROR_TYPE_INPUT = 2,
ERROR_TYPE_PARSE = 3,
ERROR_VERIFY_SIGNATURE = 4;
class SignPdfError extends Error {
constructor(R, E = ERROR_TYPE_UNKNOWN) {
super(R), (this.type = E);
}
}
(SignPdfError.TYPE_UNKNOWN = ERROR_TYPE_UNKNOWN),
(SignPdfError.TYPE_INPUT = ERROR_TYPE_INPUT),
(SignPdfError.TYPE_PARSE = ERROR_TYPE_PARSE),
(SignPdfError.VERIFY_SIGNATURE = ERROR_VERIFY_SIGNATURE);
export {
ERROR_TYPE_UNKNOWN,
ERROR_TYPE_INPUT,
ERROR_TYPE_PARSE,
ERROR_VERIFY_SIGNATURE,
SignPdfError,
};
@@ -1 +0,0 @@
const DEFAULT_SIGNATURE_LENGTH=8192,DEFAULT_BYTE_RANGE_PLACEHOLDER="**********",SUBFILTER_ADOBE_PKCS7_DETACHED="adbe.pkcs7.detached",SUBFILTER_ADOBE_PKCS7_SHA1="adbe.pkcs7.sha1",SUBFILTER_ADOBE_X509_SHA1="adbe.x509.rsa.sha1",SUBFILTER_ETSI_CADES_DETACHED="ETSI.CAdES.detached";export{DEFAULT_SIGNATURE_LENGTH,DEFAULT_BYTE_RANGE_PLACEHOLDER,SUBFILTER_ADOBE_PKCS7_DETACHED,SUBFILTER_ADOBE_PKCS7_SHA1,SUBFILTER_ADOBE_X509_SHA1,SUBFILTER_ETSI_CADES_DETACHED};
@@ -1,3 +0,0 @@
import findObject from"./findObject.min.js";import getIndexFromRef from"./getIndexFromRef.min.js";const createBufferPageWithAnnotation=(e,t,n,f)=>{e=findObject(e,t.xref,n).toString();let r,o,i;r=e.indexOf("/Annots"),i=-1<r?(o=e.indexOf("]",r),(i=e.substr(r,o+1-r)).substr(0,i.length-1)):(r=e.length,o=e.length,"/Annots [");t=getIndexFromRef(t.xref,n),n=f.toString(),i+=` ${n}]`,f=e.substr(0,r);let m="";return e.length>o&&(m=e.substr(o+1)),Buffer.concat([Buffer.from(t+` 0 obj
`),Buffer.from("<<\n"),Buffer.from(f+i+m+`
`),Buffer.from("\n>>\nendobj\n")])};export default createBufferPageWithAnnotation;
@@ -1,3 +0,0 @@
import getIndexFromRef from"./getIndexFromRef.min.js";const createBufferRootWithAcroform=(r,f,o)=>{var e=getIndexFromRef(f.xref,f.rootRef);return Buffer.concat([Buffer.from(e+` 0 obj
`),Buffer.from("<<\n"),Buffer.from(f.root+`
`),Buffer.from("/AcroForm "+o),Buffer.from("\n>>\nendobj\n")])};export default createBufferRootWithAcroform;
@@ -1,8 +0,0 @@
const createBufferTrailer=(f,r,e)=>{let o=[];return o[0]="0000000000 65535 f ",e.forEach((f,r)=>{f=("0000000000"+f).slice(-10);o[r+1]=r+` 1
${f} 00000 n `}),o=o.filter(f=>void 0!==f),Buffer.concat([Buffer.from("xref\n"),Buffer.from(r.xref.startingIndex+` 1
`),Buffer.from(o.join("\n")),Buffer.from("\ntrailer\n"),Buffer.from("<<\n"),Buffer.from(`/Size ${r.xref.maxIndex+1}
`),Buffer.from(`/Root ${r.rootRef}
`),Buffer.from(r.infoRef?`/Info ${r.infoRef}
`:""),Buffer.from(`/Prev ${r.xRefPosition}
`),Buffer.from(">>\n"),Buffer.from("startxref\n"),Buffer.from(f.length+`
`),Buffer.from("%%EOF")])};export default createBufferTrailer;
@@ -1 +0,0 @@
import getIndexFromRef from"./getIndexFromRef.min.js";const findObject=(e,t,f)=>{f=getIndexFromRef(t,f),t=t.offsets.get(f);let n=e.slice(t);return n=(n=(n=n.slice(0,n.indexOf("endobj","utf8"))).slice(n.indexOf("<<","utf8")+2)).slice(0,n.lastIndexOf(">>","utf8"))};export default findObject;
@@ -1 +0,0 @@
import SignPdfError from"./SignPdfError.min.js";const getIndexFromRef=(r,e)=>{var[o]=e.split(" "),o=parseInt(o);if(r.offsets.has(o))return o;throw new SignPdfError(`Failed to locate object "${e}".`,SignPdfError.TYPE_PARSE)};export default getIndexFromRef;
@@ -1 +0,0 @@
import getPagesDictionaryRef from"./getPagesDictionaryRef.min.js";import findObject from"./findObject.min.js";export default function getPageRef(e,t,i){var n=getPagesDictionaryRef(t),e=findObject(e,t.xref,n),t=e.indexOf("/Kids"),n=e.indexOf("[",t)+1,t=e.indexOf("]",t);const f=e.slice(n,t).toString();for(var r=[],o=0;o<f.length;o++)"R"===f[o]&&r.push(o);let a={},g=0;return r.forEach((e,t)=>{a={...a,[t+1]:f.substring(g+1,e+1)},g=e+1}),i?a[i]:a[1]}
@@ -1 +0,0 @@
import SignPdfError from"./SignPdfError.min.js";export default function getPagesDictionaryRef(r){r=/\/Pages\s+(\d+\s+\d+\s+R)/g.exec(r.root);if(null===r)throw new SignPdfError("Failed to find the pages descriptor. This is probably a problem in node-signpdf.",SignPdfError.TYPE_PARSE);return r[1]}
@@ -1 +0,0 @@
import PDFAbstractReference from"./PDFAbstractReference.min.js";const pad=(e,t)=>(Array(t+1).join("0")+e).slice(-t),escapableRe=/[\n\r\t\b\f()\\]/g,escapable={"\n":"\\n","\r":"\\r","\t":"\\t","\b":"\\b","\f":"\\f","\\":"\\\\","(":"\\(",")":"\\)"},swapBytes=e=>e.swap16();export default class PDFObject{static convert(t,a=null){if("string"==typeof t)return"/"+t;if(t instanceof String){let r=t,n=!1;for(let e=0,t=r.length;e<t;e+=1)if(127<r.charCodeAt(e)){n=!0;break}let e;return e=n?swapBytes(Buffer.from(``+r,"utf16le")):Buffer.from(r,"ascii"),`(${r=(r=(a?a(e):e).toString("binary")).replace(escapableRe,e=>escapable[e])})`}if(Buffer.isBuffer(t))return`<${t.toString("hex")}>`;if(t instanceof PDFAbstractReference)return t.toString();if(t instanceof Date){let e=`D:${pad(t.getUTCFullYear(),4)}${pad(t.getUTCMonth()+1,2)}${pad(t.getUTCDate(),2)}${pad(t.getUTCHours(),2)}${pad(t.getUTCMinutes(),2)}${pad(t.getUTCSeconds(),2)}Z`;return`(${e=a?(e=a(Buffer.from(e,"ascii")).toString("binary")).replace(escapableRe,e=>escapable[e]):e})`}if(Array.isArray(t))return`[${t.map(e=>PDFObject.convert(e,a)).join(" ")}]`;if("[object Object]"!=={}.toString.call(t))return"number"==typeof t?PDFObject.number(t):""+t;{const n=["<<"];return Object.entries(t).forEach(([e,t])=>{let r="";r=t&&-1!==t.toString().indexOf("<<")?t:PDFObject.convert(t,a),n.push(`/${e} `+r)}),n.push(">>"),n.join("\n")}}static number(e){if(-1e21<e&&e<1e21)return Math.round(1e6*e)/1e6;throw new Error("unsupported number: "+e)}}
@@ -1,28 +0,0 @@
import{DEFAULT_BYTE_RANGE_PLACEHOLDER,DEFAULT_SIGNATURE_LENGTH,SUBFILTER_ADOBE_PKCS7_DETACHED}from"./const.min.js";import PDFKitReferenceMock from"./PDFKitReferenceMock.min.js";import PNG from"png-js";import zlib from"zlib";const specialCharacters=["á","Á","é","É","í","Í","ó","Ó","ö","Ö","ő","Ő","ú","Ú","ű","Ű"],MARKERS=[65472,65473,65474,65475,65477,65478,65479,65480,65481,65482,65483,65484,65485,65486,65487],COLOR_SPACE_MAP={1:"DeviceGray",3:"DeviceRGB",4:"DeviceCMYK"};function getImage(e,t){let n;if(255===e[0]&&216===e[1])n=getJpgImage(t,e);else{if(137!==e[0]||"PNG"!==e.toString("ascii",1,4))throw new Error("Unknown image format.");n=getPngImage(t,e)}return n}function getAnnotationApparance(e,t,n){return e.ref({CropBox:[0,10,200,60],Type:"XObject",FormType:1,BBox:[0,10,200,60],Resources:`<</XObject <<
/Img${t.index} ${t.index} 0 R
>>
/Font <<
/f1 ${n.index} 0 R
>>
>>`,MediaBox:[0,10,200,60],Subtype:"Form"},null,getStream(t.index))}const getStream=e=>getConvertedText(`
1.0 1.0 1.0 rg
0.0 0.0 0.0 RG
q
q
200 0 0 50 0 10 cm
/Img${e} Do
Q
0 0 0 rg
BT
0 Tr
/f1 10.0 Tf
1.4 0 0 1 20 45.97412 Tm
ET
BT
0 Tr
/f1 10.0 Tf
1.4 0 0 1 20 33.56006 Tm
ET
Q`),getFont=(e,t)=>e.ref({Type:"Font",BaseFont:t,Encoding:"WinAnsiEncoding",Subtype:"Type1"}),getJpgImage=(e,t)=>{if(65496!==t.readUInt16BE(0))throw"SOI not found in JPEG";let n=2,a;for(;n<t.length&&(a=t.readUInt16BE(n),n+=2,!MARKERS.includes(a));)n+=t.readUInt16BE(n);if(!MARKERS.includes(a))throw"Invalid JPEG.";n+=2;var r=t[n++],o=t.readUInt16BE(n),i=(n+=2,t.readUInt16BE(n)),l=(n+=2,t[n++]),l=COLOR_SPACE_MAP[l],r={Type:"XObject",Subtype:"Image",BitsPerComponent:r,Width:i,Height:o,ColorSpace:l,Filter:"DCTDecode"},i=("DeviceCMYK"===l&&(r.Decode=[1,0,1,0,1,0,1,0]),e.ref(r,null,t));return i},getPngImage=(e,t)=>{var t=new PNG(t),n=t.hasAlphaChannel,a={Type:"XObject",Subtype:"Image",BitsPerComponent:n?8:t.bits,Width:t.width,Height:t.height,Filter:"FlateDecode"};if(n||(r=e.ref({Predictor:15,Colors:t.colors,BitsPerComponent:t.bits,Columns:t.width}),a.DecodeParms=r),0===t.palette.length?a.ColorSpace=t.colorSpace:(r=e.ref({stream:new Buffer(t.palette)}),a.ColorSpace=["Indexed","DeviceRGB",t.palette.length/3-1,r]),null!=t.transparency.grayscale){var r=t.transparency.grayscale;a.Mask=[r,r]}else if(t.transparency.rgb){var o,r=t.transparency["rgb"],i=[];for(o of r)i.push(o,o);a.Mask=i}else t.transparency.indexed?loadIndexedAlphaChannel(t):n&&(splitAlphaChannel(t),r=getSmask(e,t),a.Mask=r);return e.ref(a,null,t.imgData)},loadIndexedAlphaChannel=e=>{const o=e.transparency.indexed;return e.decodePixels(n=>{var a=new Buffer(e.width*e.height);let r=0;for(let e=0,t=n.length;e<t;e++)a[r++]=o[n[e]];e.alphaChannel=zlib.deflateSync(a)})},splitAlphaChannel=d=>{d.decodePixels(t=>{let e,n;var a=d.colors,r=d.width*d.height,o=new Buffer(r*a),i=new Buffer(r);let l=n=e=0;for(var c=t.length,g=16===d.bits?1:0;l<c;){for(let e=0;e<a;e++)o[n++]=t[l++],l+=g;i[e++]=t[l++],l+=g}d.imgData=zlib.deflateSync(o),d.alphaChannel=zlib.deflateSync(i)})},getSmask=(e,t)=>{let n;return console.log("image.hasAlphaChannel ",t.hasAlphaChannel),t.hasAlphaChannel&&(console.log("image.alphaChannel ",t.alphaChannel),n=e.ref({Type:"XObject",Subtype:"Image",Height:t.height,Width:t.width,BitsPerComponent:8,Filter:"FlateDecode",ColorSpace:"DeviceGray",Decode:[0,1],stream:t.alphaChannel})),n},getConvertedText=e=>e.split("").map(e=>specialCharacters.includes(e)?getOctalCodeFromCharacter(e):e).join(""),getOctalCodeFromCharacter=e=>"\\"+e.charCodeAt(0).toString(8),pdfkitAddPlaceholder=({pdf:e,pdfBuffer:a,reason:r,contactInfo:t="emailfromp1289@gmail.com",name:n="Name from p12",location:o="Location from p12",signatureLength:i=DEFAULT_SIGNATURE_LENGTH,byteRangePlaceholder:l=DEFAULT_BYTE_RANGE_PLACEHOLDER,subFilter:c=SUBFILTER_ADOBE_PKCS7_DETACHED,sign:g})=>{var d=getFont(e,"Helvetica"),s=getFont(e,"ZapfDingbats"),p=getFont(e,"Helvetica"),f=g.Base64,f=getAnnotationApparance(e,getImage(Buffer.from(f,"base64"),e),p,g),p=e.ref({Type:"Sig",Filter:"Adobe.PPKLite",SubFilter:c,ByteRange:[0,l,l,l],Contents:Buffer.from(String.fromCharCode(0).repeat(i)),Reason:new String(r),M:new Date,ContactInfo:new String(t),Name:new String(n),Location:new String(o)}),h=a.lastIndexOf("/Type /AcroForm"),c=-1!==h;let m=[],C;if(c){let e=h;var S=h-10;let t="",n=11;for(n;n<22;n+=1){var A=a.slice(h-n,S).toString();if("\n"===A[0])break;t=A,e=h-n}l=a.slice(e),i=l.slice(0,l.indexOf("endobj")).toString(),r=(C=parseInt(t),i.slice(i.indexOf("/Fields [")+9,i.indexOf("]")));m=r.split(" ").filter((e,t)=>t%3==0).map(e=>new PDFKitReferenceMock(e))}t=g.Left,n=g.Bottom,o=t+g.Width,l=n+g.Height,i=e.ref({Type:"Annot",Subtype:"Widget",FT:"Sig",Rect:[t,n,o,l],V:p,T:new String("Signature"+(m.length+1)),F:4,P:e.page.dictionary,AP:`<</N ${f.index} 0 R>>`,DA:new String("/Helvetica 0 Tf 0 g")});e.page.dictionary.data.Annots=[i];let T;return T=c?e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i],DR:`<</Font
<</Helvetica ${d.index} 0 R/ZapfDingbats ${s.index} 0 R>>
>>`},C):e.ref({Type:"AcroForm",SigFlags:3,Fields:[...m,i]}),{signature:p,form:e._root.data.AcroForm=T,widget:i}};export default pdfkitAddPlaceholder;
@@ -1,87 +0,0 @@
import {
DEFAULT_BYTE_RANGE_PLACEHOLDER,
DEFAULT_SIGNATURE_LENGTH,
SUBFILTER_ADOBE_PKCS7_DETACHED,
} from './const.min.js';
import { SignPdfError } from './SignPdfError.min.js';
import {
PDFArray,
PDFDict,
PDFHexString,
PDFName,
PDFNumber,
PDFInvalidObject,
PDFString,
} from 'pdf-lib';
const pdflibAddPlaceholder = ({
pdfDoc: e = void 0,
pdfPage: o = void 0,
reason: t,
contactInfo: r = 'emailfromp1289@gmail.com',
name: i = 'Name from p12',
location: n,
signingTime: a = void 0,
signatureLength: P = DEFAULT_SIGNATURE_LENGTH,
byteRangePlaceholder: F = DEFAULT_BYTE_RANGE_PLACEHOLDER,
subFilter: D = SUBFILTER_ADOBE_PKCS7_DETACHED,
widgetRect: f = [0, 0, 0, 0],
appName: g = void 0,
}) => {
if (void 0 === e && void 0 === o)
throw new SignPdfError('PDFDoc or PDFPage must be set.', SignPdfError.TYPE_INPUT);
var e = e ?? o.doc,
o = o ?? e.getPages()[0],
m = PDFArray.withContext(e.context),
F =
(m.push(PDFNumber.of(0)),
m.push(PDFName.of(F)),
m.push(PDFName.of(F)),
m.push(PDFName.of(F)),
PDFHexString.of(String.fromCharCode(0).repeat(P))),
P = g ? { App: { Name: g } } : {},
g = e.context.obj({
Type: 'Sig',
Filter: 'Adobe.PPKLite',
SubFilter: D,
ByteRange: m,
Contents: F,
Reason: PDFString.of(t),
M: PDFString.fromDate(a ?? new Date()),
ContactInfo: PDFString.of(r),
Name: PDFString.of(i),
Location: PDFString.of(n),
Prop_Build: { Filter: { Name: 'Adobe.PPKLite' }, ...P },
}),
D = new Uint8Array(g.sizeInBytes()),
m = (g.copyBytesInto(D, 0), PDFInvalidObject.of(D)),
F = e.context.register(m);
const s = PDFArray.withContext(e.context);
f.forEach(e => s.push(PDFNumber.of(e)));
(t = e.context.formXObject([], { BBox: f, Resources: {} })),
(a = e.context.obj({
Type: 'Annot',
Subtype: 'Widget',
FT: 'Sig',
Rect: s,
V: F,
T: PDFString.of('Signature1'),
F: 4,
P: o.ref,
AP: { N: e.context.register(t) },
})),
(r = e.context.register(a));
let c = o.node.lookupMaybe(PDFName.of('Annots'), PDFArray),
d =
((c = void 0 === c ? e.context.obj([]) : c).push(r),
o.node.set(PDFName.of('Annots'), c),
e.catalog.lookupMaybe(PDFName.of('AcroForm'), PDFDict));
void 0 === d &&
((d = e.context.obj({ Fields: [] })),
(i = e.context.register(d)),
e.catalog.set(PDFName.of('AcroForm'), i));
let N;
N = d.has(PDFName.of('SigFlags')) ? d.get(PDFName.of('SigFlags')) : PDFNumber.of(0);
n = PDFNumber.of(3 | N.asNumber());
d.set(PDFName.of('SigFlags'), n), d.get(PDFName.of('Fields')).push(r);
};
export { pdflibAddPlaceholder };
@@ -1,2 +0,0 @@
import PDFObject from"./pdfObject.min.js";import PDFKitReferenceMock from"./PDFKitReferenceMock.min.js";import removeTrailingNewLine from"./removeTrailingNewLine.min.js";import{DEFAULT_SIGNATURE_LENGTH,SUBFILTER_ADOBE_PKCS7_DETACHED}from"./const.min.js";import pdfkitAddPlaceholder from"./pdfkitAddPlaceholder.min.js";import getIndexFromRef from"./getIndexFromRef.min.js";import readPdf from"./readPdf.min.js";import getPageRef from"./getPageRef.min.js";import createBufferRootWithAcroform from"./createBufferRootWithAcroform.min.js";import createBufferPageWithAnnotation from"./createBufferPageWithAnnotation.min.js";import createBufferTrailer from"./createBufferTrailer.min.js";const isContainBufferRootWithAcroform=e=>{e=/\/AcroForm\s+(\d+\s\d+\sR)/g.exec(e.toString());return null!=e&&null!=e[1]&&""!==e[1]},getAssembledPdf=(e,r,f,o)=>{let t=e;return t=Buffer.concat([t,Buffer.from("\n"),Buffer.from(r+` 0 obj
`),Buffer.from(PDFObject.convert(f))]),o&&(t=Buffer.concat([t,Buffer.from("\nstream\n"),Buffer.from(o),Buffer.from("\nendstream")])),t=Buffer.concat([t,Buffer.from("\nendobj\n")])},plainAddPlaceholder=({pdfBuffer:e,reason:r,contactInfo:f="emailfromp1289@gmail.com",name:o="Name from p12",location:t="Location from p12",signatureLength:n=DEFAULT_SIGNATURE_LENGTH,subFilter:i=SUBFILTER_ADOBE_PKCS7_DETACHED,sign:m})=>{let a=removeTrailingNewLine(e);const c=readPdf(a);var d=getPageRef(a,c,m.Page),u=getIndexFromRef(c.xref,d);const l=new Map;var s={ref:(e,r,f)=>{c.xref.maxIndex+=1;r=null!=r?r:c.xref.maxIndex;return l.set(r,a.length+1),a=getAssembledPdf(a,r,e,f),new PDFKitReferenceMock(c.xref.maxIndex)},page:{dictionary:new PDFKitReferenceMock(u,{data:{Annots:[]}})},_root:{data:{}}},{form:s,widget:e}=pdfkitAddPlaceholder({pdf:s,pdfBuffer:e,reason:r,contactInfo:f,name:o,location:t,signatureLength:n,subFilter:i,sign:m});return isContainBufferRootWithAcroform(a)||(r=getIndexFromRef(c.xref,c.rootRef),l.set(r,a.length+1),a=Buffer.concat([a,Buffer.from("\n"),createBufferRootWithAcroform(a,c,s)])),l.set(u,a.length+1),a=Buffer.concat([a,Buffer.from("\n"),createBufferPageWithAnnotation(a,c,d,e)]),a=Buffer.concat([a,Buffer.from("\n"),createBufferTrailer(a,c,l)])};export default plainAddPlaceholder;
@@ -1 +0,0 @@
import readRefTable from"./readRefTable.min.js";import findObject from"./findObject.min.js";const getValue=(e,t)=>{let r=e.indexOf(t);if(-1!==r)return e=e.slice(r),-1===(r=e.indexOf("/",1))&&(r=e.indexOf(">",1)),e.slice(t.length+1,r).toString().trim()},readPdf=e=>{var t=e.lastIndexOf("trailer"),r=e.slice(t,e.length-6),f=r.slice(r.lastIndexOf("startxref")+10).toString(),f=parseInt(f),i=readRefTable(e),n=getValue(r,"/Root");return{xref:i,rootRef:n,root:findObject(e,i,n).toString(),infoRef:getValue(r,"/Info"),trailerStart:t,previousXrefs:[],xRefPosition:f}};export default readPdf;
@@ -1 +0,0 @@
import SignPdfError from"./SignPdfError.min.js";import xrefToRefMap from"./xrefToRefMap.min.js";const getLastTrailerPosition=e=>{var r=e.lastIndexOf(Buffer.from("trailer","utf8")),r=e.slice(r,e.length-6),e=r.slice(r.lastIndexOf(Buffer.from("startxref","utf8"))+10).toString();return parseInt(e)},getXref=(e,r)=>{let t=e.slice(r);e=t.indexOf(Buffer.from("xref","utf8"));if(-1===e)throw new SignPdfError(`Could not find xref anywhere at or after ${r}.`,SignPdfError.TYPE_PARSE);if(0<e&&""!==t.slice(0,e).toString().replace(/\s*/g,""))throw new SignPdfError(`Expected xref at ${r} but found other content.`,SignPdfError.TYPE_PARSE);r=t.indexOf(Buffer.from("%%EOF","utf8"));if(-1===r)throw new SignPdfError("Expected EOF after xref and trailer but could not find one.",SignPdfError.TYPE_PARSE);if(!(r=(t=(t=(t=t.slice(0,r)).slice(e+4)).slice(t.indexOf("\n")+1)).toString().split("/Size")[1]))throw new SignPdfError("Size not found in xref table.",SignPdfError.TYPE_PARSE);if(null===(r=/^\s*(\d+)/.exec(r)))throw new SignPdfError("Failed to parse size of xref table.",SignPdfError.TYPE_PARSE);var r=parseInt(r[1]),[e,f]=t.toString().split("trailer");let n;null!=f.split("/Prev")[1]&&([,f]=/Prev (\d+)/g.exec(f),n=f);f=xrefToRefMap(e);return{size:r,prev:n,xRefContent:f}},getFullXrefTable=e=>{var r=getLastTrailerPosition(e),t=getXref(e,r);return void 0===t.prev?t.xRefContent:(e=e.slice(0,r),r=getFullXrefTable(e),new Map([...r,...t.xRefContent]))},readRefTable=e=>{e=getFullXrefTable(e);return{startingIndex:0,maxIndex:Math.max(...e.keys()),offsets:e}};export default readRefTable;export{getLastTrailerPosition,getXref,getFullXrefTable};
@@ -1 +0,0 @@
import SignPdfError from"./SignPdfError.min.js";const sliceLastChar=(r,e)=>{return r.slice(r.length-1).toString()===e?r.slice(0,r.length-1):r},removeTrailingNewLine=r=>{if(!(r instanceof Buffer))throw new SignPdfError("PDF expected as Buffer.",SignPdfError.TYPE_INPUT);r=sliceLastChar(r,"\n");if("\n%%EOF"!==(r=sliceLastChar(r,"\r")).slice(r.length-6).toString())throw new SignPdfError("A PDF file must end with an EOF line.",SignPdfError.TYPE_PARSE);return r};export default removeTrailingNewLine;
@@ -1 +0,0 @@
import SignPdfError from"./SignPdfError.min.js";const xrefToRefMap=r=>{r=r.split("\n").filter(r=>""!==r);let n=0,t=0;const f=new Map;return r.forEach(r=>{r=r.split(" ");if(2===r.length)n=parseInt(r[0]),t=parseInt(r[1]);else{if(t<=0)throw new SignPdfError("Too many lines in xref table.",SignPdfError.TYPE_PARSE);--t;var[r,,e]=r;if("f"!==e.trim()){if("n"!==e.trim())throw new SignPdfError(`Unknown in-use flag "${e}". Expected "n" or "f".`,SignPdfError.TYPE_PARSE);if(!/^\d+$/.test(r.trim()))throw new SignPdfError(`Expected integer offset. Got "${r}".`,SignPdfError.TYPE_PARSE);e=parseInt(r.trim());f.set(n,e)}n+=1}}),f};export default xrefToRefMap;