It has taken me some time to figure out, but I have successfully added a signature field to a PDF generated with pdfkit. I add the field with the following function:
const formSig = ((pdfDoc, name, x, y, w, h, options = {}) => {
const annotOptions = {
...options,
FT: 'Sig',
}
pdfDoc.formAnnotation(name, null, x, y, w, h, annotOptions)
});
However, I now want to control which fields are locked when someone signs the document so that I can request multiple signatures. I know what steps I need to take, but I'm not sure how to do it.
- Add a signature field lock dictionary with
Type
set toSigFieldLock
, Action set toInclude
andFields
set to an array of field name strings. - Add a
Lock
entry to the signature field that is a reference to the lock dictionary.
I'm struggling to figure out which method will allow me to add the dictionary, find its reference and include the reference when adding the signature field.
Update
I believe I've figured out how to create the dictionary and get its reference to add to the field options, but the dictionary isn't being written to the stream.
Does anyone know pdfkit well enough to point me in the right direction?
CodePudding user response:
I managed to get it working. In pdfkit, you can create basically any dictionary object using the ref()
method. The other thing I learned is that to create the array of fields for the lock dictionary, I needed to convert each string to a String
for pdfkit to encode it properly.
I used the following code:
const formSig = ((pdfDoc, name, x, y, w, h, fieldsToLock, options = {}) => {
// Converts the array of strings to an array of Strings
const lockArray = fieldsToLock.map((fieldName) => {
return new String(fieldName);
})
// Call the function to create the lock dictionary and capture its reference
const lockRef = lockDict(pdfDoc, lockArray)
// Build the annotation options including the field type, make the field require and a reference
// to the lock dictionary in the Lock field
const annotOptions = {
...options,
FT: 'Sig',
Ff: 2,
Lock: lockRef,
}
// Add the field to the dictionary
pdfDoc.formAnnotation(name, null, x, y, w, h, annotOptions)
});
const lockDict = ((pdfDoc, locks) => {
// Build the Lock dictionary object to be added to the PDF
const dict = {
Type: 'SigFieldLock',
Action: 'Include',
Fields: locks
}
// Create a dictionary object reference and capture the reference
let dictRef = pdfDoc.ref(dict);
// Write the reference to the PDF stream
dictRef.end();
// Return the reference
return fieldRef;
});
I will need to add some error handling and logic (in case there are no fields to lock), but it works. I've tested it with multiple signatures locking different fields and multiple signatures locking the same fields.