Skip to main content
Known Participant
July 18, 2022
Answered

How to use Javascript to detect a signed Acrobat document?

  • July 18, 2022
  • 3 replies
  • 12892 views

Hi,

 

BACKGROUND:

I am using an Action Wizard in Adobe Acrobat Pro DC to automatically label a batch of pdf's. It has various steps: JavaScript (Initial Error Trapping) > Remove Hidden Information >  Reduce File Size > Save to "Prepped" Folder > Add Header & Footer > JaveScript (Adding incremental labels to all documents in "Prepped" Folder so if there are 4 documents, it will label them in sequence as EX01, EX02, EX03, and EX04).

 

REQUEST:

1) I need to bring up an error message for the user when a signed pdf is detected in the batch b/c once we upgraded to Adobe Acrobat Pro DC, such files are skipped and therefore, not processed. I researched this and found it is b/c a signature in the pdf makes it so "Changing the Document" is not allowed.

Note: In my example, Document 3 is the signed pdf and all the processing steps above are skipped and the file is not saved in the "Prepped" folder.

 

I tried the following to alert the user of a signed pdf but it did not work.

 

       if (securityhandler == null) {app.alert(event.target.documentFileName + " is signed and cannot be         labeled. It will be skipped.");}

 

2) As an added bonus, it would be great if you could give me an idea on how I can up the numbering by one once a signed pdf is detected (Can I just add "+1" to the iteration of "global.iteration++"?). Right now, the signed document is skipped and the next document gets assigned its number such that the numbering is off.

Note: In my example, Document 3 is the signed pdf and all the processing steps above are skipped and the file is not saved in the "Prepped" folder. Document 4 instead is labeled as EX03 instead of EX04.

 

Thanks so much!

Sue

This topic has been closed for replies.
Correct answer try67

Document 3 was digitally signed using certificates. Does that help? I have attached the sample files.


Try it with this code:

 

var isSigned = false;
for (var i=0; i<this.numFields; i++) {
	var fname = this.getNthFieldName(i);
	var f = this.getField(fname);
	if (f==null) continue;
	if (f.type=="signature" && f.value!="") {isSigned = true; break;}
}
if (isSigned) app.alert("This document is signed.");

 

The securityHandler property is for document encryption, not for signatures.

3 replies

JR Boulay
Community Expert
July 20, 2022

"I don't know how to deploy this in my action wizard. Can you advise?"

 

1.

 

2.

 

3.

Acrobate du PDF, InDesigner et Photoshopographe
JR Boulay
Community Expert
July 19, 2022

You don't need JavaScript, you should start the Preflight process by using this check profile:

 

Acrobate du PDF, InDesigner et Photoshopographe
suemo22Author
Known Participant
July 19, 2022

Hmmm, I don't know how to deploy this in my action wizard. Can you advise? I am using an Action Wizard in Adobe Acrobat Pro DC to automatically label a batch of pdf's. It has various steps:

 

  1. JavaScript (Initial Error Trapping) 
  2. Remove Hidden Information 
  3. Reduce File Size
  4. Save to "Prepped" Folder
  5. Add Header & Footer 
  6. JavaScript (Adding incremental labels to all documents in "Prepped" Folder so if there are 4 documents, it will label them in sequence as EX01, EX02, EX03, and EX04).
suemo22Author
Known Participant
July 20, 2022

Here is the partial code for Step 8 (Javascript). The original code is in ilatics. My comments/questions are in bold.

 

// place labels
global.DoPlaceDocNumbers = app.trustedFunction(function(oOrigDoc) {
app.beginPriv();

// test whether the file is signed; if it is not, it can be labeled. Otherwise it is skipped.
if (oOrigDoc.securityHandler == null) <--I need this to test if document is signed or not. If it is not, then all steps in italics below should continue. I realize it is pointing to encryption and I am trying to integrate your code instead by adding:

var isSigned = false;

for (var i=0; i<this.numFields; i++) {

         var fname = this.getNthFieldName(i);

         var f = this.getField(fname);

         if (f==null) continue;

         if (f.type=="signature" && f.value!="") {isSigned = true; break;}

}

but no luck so far due to syntax errors.

 

{var oTrgDoc = oOrigDoc,
nPgStart,
nPgEnd,
nPgTrgStart,
cBkCol = ["T"];

/* set background color */
switch (global.DocNumAction.strBackgroundCol.toString()) {
case "Transparent":
cBkCol = ["T"];
break;
case "Yellow":
cBkCol = ["RGB", 1, 1, 0];
break;
case "Green":
cBkCol = ["RGB", 0, 1, 0];
break;
case "Blue":
cBkCol = ["RGB", 0, 0, 1];
break;
case "Grey":
cBkCol = ["RGB", .7, .7, .7];
break;
case "White":
cBkCol = ["RGB", 1, 1, 1]
}

/* set page range selection */
switch (global.DocNumAction.strPgRangeSel) {
case "rAll":
nPgTrgStart = nPgStart = 0,
nPgEnd = oOrigDoc.numPages - 1;
break;
case "rCur":
nPgTrgStart = nPgEnd = nPgStart = oOrigDoc.hidden ? 0 : oOrigDoc.pageNum;
break;
case "rFro":
nPgTrgStart = nPgStart = Number(global.DocNumAction.strStrtPg) - 1, nPgTrgStart > oOrigDoc.numPages - 1 &&
(nPgTrgStart = oOrigDoc.numPages - 1),
nPgEnd = Number(global.DocNumAction.strEndPg) - 1,
nPgEnd > oOrigDoc.numPages - 1 &&
(nPgEnd = oOrigDoc.numPages - 1)
}

/* process the selected page range */
for (var nNumPages = nPgEnd - nPgStart + 1,
nCurPgNum = nPgStart,
nPg = 0; nNumPages > nPg; nPg++, nCurPgNum++, nPgTrgStart++) {
var strExample = global.DocNumAction.strLabelPrefix;
global.DocNumAction.bIncludeDocNum &&
(strExample += " "),
strExample += global.DocNumAction.nCurrentDocNum, global.DocNumAction.bIncludePageNum &&
(
strExample += eval("'" + global.DocNumAction.strPageNumPrefix + "'") + ("" + (nCurPgNum + 1)), global.DocNumAction.bPageNumPostfix &&
(strExample += " of " + oOrigDoc.numPages)
);

var rcPage = oOrigDoc.getPageBox("Crop", nCurPgNum),
mxToDefaultCoords = (new Matrix2D).fromRotated(oOrigDoc, nCurPgNum),
nPgRot = oOrigDoc.getPageRotation(nCurPgNum),
rcRot = [],
nAlign,
nMargX = 72 * +global.DocNumAction.nMarginX;

/* set margins for whichever text area is being processed */
switch (global.DocNumAction.strHorzPos) {
case "PosL":
strAlign = "left",
rcRot[0] = nMargX,
rcRot[2] = nMargX + nLabWidth;
break;
case "PosC":
strAlign = "center",
rcRot[0] = rcPage[2] / 2 - nLabWidth / 2,
rcRot[2] = rcPage[2] / 2 + nLabWidth / 2;
break;
case "PosR":
strAlign = "right",
rcRot[0] = rcPage[2] - nMargX - nLabWidth,
rcRot[2] = rcPage[2] - nMargX
}
var nMargY = 72 * Number(global.DocNumAction.nMarginY),
nLines = 1,
oMtch = strExample.match(/(\n)/g);
oMtch && (nLines += oMtch.length);
var bxHght = nLines * (nLabLineHeight + 1);

/* calculate additional margin / placement information */
switch (global.DocNumAction.strVertPos) {
case "PosT":
rcRot[1] = rcPage[1] - nMargY - bxHght,
rcRot[3] = rcPage[1] - nMargY;
break;
case "PosB":
rcRot[1] = nMargY,
rcRot[3] = nMargY + bxHght
}

/* same thing for annotation */
var rectAnnot = mxToDefaultCoords.transform(rcRot),
annot = oTrgDoc.getAnnot(nPgTrgStart, "DocNumberLabel");
annot && annot.destroy(),
strExample = strExample.replace(/\r\n/g, "\r"),
oTrgDoc.addAnnot(
{
type: "FreeText",
page: nPgTrgStart,
rect: rectAnnot,
rotate: nPgRot,
width: 0,
fillColor: cBkCol,
readOnly: "Lckd" == global.DocNumAction.strBoxStateSel,
richContents: [{
textColor: ["RGB", 0, 0, 0],
textSize: nLabLineHeight,
alignment: strAlign,
text: strExample
}],
name: "DocNumberLabel"
})
}

/* if flattening pages */
if (oTrgDoc.flattenPages(),
global.DocNumAction.bSaveWPostFx) {
var cSavePath = oOrigDoc.path.replace(/\/[^\/]+$/, "/"); // may need adjustment to remove residual escaping inserted during translation / transition from older format

// KTA added this to replace "prepped" with "labeled" if using a standard tree
cSavePath = setOutputFolder(cSavePath);

/*********************************************************



var cSavePrefix = "00000" + global.DocNumAction.nCurrentDocNum.toString();
cSavePrefix = cSavePrefix.slice(-5);
cSavePath += "Exh" + cSavePrefix + "_";
*************************************************************/

// app.alert("Number of pages is " + nNumPages);
cSavePath += oOrigDoc.documentFileName.replace(/\.pdf/, ""),
"DnPr" == global.DocNumAction.strTotalPgNumInName &&
(cSavePath += " - ", cSavePath += nNumPages,
1 == nNumPages && (cSavePath += " page"),
1 != nNumPages && (cSavePath += " pages")
),
"None" == global.DocNumAction.strTotalPgNumInName,
cSavePath += ".pdf",
cSavePath = cSavePath.replace(/\,/g, ""),
oTrgDoc.saveAs(cSavePath)
}
} // end of test for whether the document has a signature
else { // document is signed and should be skipped
app.alert(event.target.documentFileName + " is signed and cannot be labeled. It will be skipped.");<--This is where I would like to insert your code in part that alerts user to signed documents. I want it to bump up the iteration. No luck so far.: if (isSigned) app.alert("This document is signed."); globaliteration++ 
}
global.iteration++; 

app.endPriv()
} // end of DoPlaceDocNumbers
) // end of label placer function declaration
} // end IF global.DocNumAction is undefined


Below is clean version of code in part, without my comments (I removed comments). It was originally written to catch encryption but I am trying to integrate your code.

 

// place labels
global.DoPlaceDocNumbers = app.trustedFunction(function(oOrigDoc) {
app.beginPriv();

// test whether the file is encrypted; if it is not, it can be labeled. Otherwise it is skipped.
if (oOrigDoc.securityHandler == null) {

var oTrgDoc = oOrigDoc,
nPgStart,
nPgEnd,
nPgTrgStart,
cBkCol = ["T"];

/* set background color */
switch (global.DocNumAction.strBackgroundCol.toString()) {
case "Transparent":
cBkCol = ["T"];
break;
case "Yellow":
cBkCol = ["RGB", 1, 1, 0];
break;
case "Green":
cBkCol = ["RGB", 0, 1, 0];
break;
case "Blue":
cBkCol = ["RGB", 0, 0, 1];
break;
case "Grey":
cBkCol = ["RGB", .7, .7, .7];
break;
case "White":
cBkCol = ["RGB", 1, 1, 1]
}

/* set page range selection */
switch (global.DocNumAction.strPgRangeSel) {
case "rAll":
nPgTrgStart = nPgStart = 0,
nPgEnd = oOrigDoc.numPages - 1;
break;
case "rCur":
nPgTrgStart = nPgEnd = nPgStart = oOrigDoc.hidden ? 0 : oOrigDoc.pageNum;
break;
case "rFro":
nPgTrgStart = nPgStart = Number(global.DocNumAction.strStrtPg) - 1, nPgTrgStart > oOrigDoc.numPages - 1 &&
(nPgTrgStart = oOrigDoc.numPages - 1),
nPgEnd = Number(global.DocNumAction.strEndPg) - 1,
nPgEnd > oOrigDoc.numPages - 1 &&
(nPgEnd = oOrigDoc.numPages - 1)
}

/* process the selected page range */
for (var nNumPages = nPgEnd - nPgStart + 1,
nCurPgNum = nPgStart,
nPg = 0; nNumPages > nPg; nPg++, nCurPgNum++, nPgTrgStart++) {
var strExample = global.DocNumAction.strLabelPrefix;
global.DocNumAction.bIncludeDocNum &&
(strExample += " "),
strExample += global.DocNumAction.nCurrentDocNum, global.DocNumAction.bIncludePageNum &&
(
strExample += eval("'" + global.DocNumAction.strPageNumPrefix + "'") + ("" + (nCurPgNum + 1)), global.DocNumAction.bPageNumPostfix &&
(strExample += " of " + oOrigDoc.numPages)
);

var rcPage = oOrigDoc.getPageBox("Crop", nCurPgNum),
mxToDefaultCoords = (new Matrix2D).fromRotated(oOrigDoc, nCurPgNum),
nPgRot = oOrigDoc.getPageRotation(nCurPgNum),
rcRot = [],
nAlign,
nMargX = 72 * +global.DocNumAction.nMarginX;

/* set margins for whichever text area is being processed */
switch (global.DocNumAction.strHorzPos) {
case "PosL":
strAlign = "left",
rcRot[0] = nMargX,
rcRot[2] = nMargX + nLabWidth;
break;
case "PosC":
strAlign = "center",
rcRot[0] = rcPage[2] / 2 - nLabWidth / 2,
rcRot[2] = rcPage[2] / 2 + nLabWidth / 2;
break;
case "PosR":
strAlign = "right",
rcRot[0] = rcPage[2] - nMargX - nLabWidth,
rcRot[2] = rcPage[2] - nMargX
}
var nMargY = 72 * Number(global.DocNumAction.nMarginY),
nLines = 1,
oMtch = strExample.match(/(\n)/g);
oMtch && (nLines += oMtch.length);
var bxHght = nLines * (nLabLineHeight + 1);

/* calculate additional margin / placement information */
switch (global.DocNumAction.strVertPos) {
case "PosT":
rcRot[1] = rcPage[1] - nMargY - bxHght,
rcRot[3] = rcPage[1] - nMargY;
break;
case "PosB":
rcRot[1] = nMargY,
rcRot[3] = nMargY + bxHght
}

/* same thing for annotation */
var rectAnnot = mxToDefaultCoords.transform(rcRot),
annot = oTrgDoc.getAnnot(nPgTrgStart, "DocNumberLabel");
annot && annot.destroy(),
strExample = strExample.replace(/\r\n/g, "\r"),
oTrgDoc.addAnnot(
{
type: "FreeText",
page: nPgTrgStart,
rect: rectAnnot,
rotate: nPgRot,
width: 0,
fillColor: cBkCol,
readOnly: "Lckd" == global.DocNumAction.strBoxStateSel,
richContents: [{
textColor: ["RGB", 0, 0, 0],
textSize: nLabLineHeight,
alignment: strAlign,
text: strExample
}],
name: "DocNumberLabel"
})
}

/* if flattening pages */
if (oTrgDoc.flattenPages(),
global.DocNumAction.bSaveWPostFx) {
var cSavePath = oOrigDoc.path.replace(/\/[^\/]+$/, "/"); // may need adjustment to remove residual escaping inserted during translation / transition from older format

cSavePath = setOutputFolder(cSavePath);

/*********************************************************
var cSavePrefix = "00000" + global.DocNumAction.nCurrentDocNum.toString();
cSavePrefix = cSavePrefix.slice(-5);
cSavePath += "Exh" + cSavePrefix + "_";
*************************************************************/

// app.alert("Number of pages is " + nNumPages);
cSavePath += oOrigDoc.documentFileName.replace(/\.pdf/, ""),
"DnPr" == global.DocNumAction.strTotalPgNumInName &&
(cSavePath += " - ", cSavePath += nNumPages,
1 == nNumPages && (cSavePath += " page"),
1 != nNumPages && (cSavePath += " pages")
),
"None" == global.DocNumAction.strTotalPgNumInName,
cSavePath += ".pdf",
cSavePath = cSavePath.replace(/\,/g, ""),
oTrgDoc.saveAs(cSavePath)
}
} // end of test for whether the document has a security handler (i.e. is encrypted)
else { // document is encrypted and should be skipped
app.alert(event.target.documentFileName + " is encrypted and cannot be labeled. It will be skipped.");
}
global.iteration++;

app.endPriv()
} // end of DoPlaceDocNumbers
) // end of label placer function declaration

 

try67
Community Expert
July 19, 2022

It's important to spell things correctly when writing a script. Try this:

 

if (this.securityHandler == null) {app.alert(this.documentFileName + " is signed and cannot be labeled. It will be skipped.");}
else global.iteration++;
suemo22Author
Known Participant
July 19, 2022

Hi,

It is putting up this error for all documents, even the unsigned ones:

  • Document 1 (unsigned)
  • Document 2 (unsigned)
  • Document 3 (signed)
  • Document 4 (unsigned)

 

How do I specifically make it recognize the one that has a signature? Also, the iteration did not work. It still labeled Document 4 as EX03 instead of EX04.

 

Thanks in advance.

Sue

suemo22Author
Known Participant
July 19, 2022

As added info, when I try to manually label Document 3 (signed) , it states:

      "You do not have sufficient permissions to perform this task"

 

I really need a way to identify such documents, alert the user, and skip these.