Home > Software design >  Using pdfkit, how do I add a Lock dictionary to PDF?
Using pdfkit, how do I add a Lock dictionary to PDF?

Time:08-16

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.

  1. Add a signature field lock dictionary with Type set to SigFieldLock, Action set to Include and Fields set to an array of field name strings.
  2. 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.

  • Related