diff --git a/README.md b/README.md
index 56e928a..45a83b2 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# ZgaPdfSigner
A javascript tool to sign a pdf in web browser.
+And it also can be used in Google Apps Script.
PS: __ZGA__ is the abbreviation of my father's name.
And I use this name to hope the merits from this application will be dedicated to my parents.
@@ -15,7 +16,7 @@ Just import the dependencies and this tool.
```html
-
+
```
## Let's sign
@@ -35,7 +36,7 @@ async function sign1(pdf, cert, pwd){
p12cert: cert,
pwd: pwd,
};
- var signer = new PdfSigner(sopt);
+ var signer = new Zga.PdfSigner(sopt);
return await signer.sign(pdf);
}
```
@@ -67,7 +68,7 @@ async function sign2(pdf, cert, pwd, imgdat, imgtyp){
imgType: imgtyp,
},
};
- var signer = new PdfSigner(sopt);
+ var signer = new Zga.PdfSigner(sopt);
return await signer.sign(pdf);
}
```
@@ -78,9 +79,41 @@ Sign with a visible signature of drawing a text.
//TODO
```
+Use it in Google Apps Script
+
+```js
+// Simulate setTimeout function for pdf-lib
+function setTimeout(func, sleep){
+ Utilities.sleep(sleep);
+ func();
+}
+// Simulate window for node-forge
+var window = globalThis;
+// Load pdf-lib
+eval(UrlFetchApp.fetch("https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.min.js").getContentText());
+// Load node-forge
+eval(UrlFetchApp.fetch("https://unpkg.com/node-forge@1.3.1/dist/forge.min.js").getContentText());
+// Load ZgaPdfSigner
+eval(UrlFetchApp.fetch("https://github.com/zboris12/zgapdfsigner/releases/download/1.1.0/zgapdfsigner.js").getContentText());
+
+// Load pdf, certificate
+var pdfBlob = DriveApp.getFilesByName("_test.pdf").next().getBlob();
+var certBlob = DriveApp.getFilesByName("_test.pfx").next().getBlob();
+// Sign the pdf
+var sopt = {
+ p12cert: new Uint8Array(certBlob.getBytes()),
+ pwd: "some passphrase",
+};
+var signer = new Zga.PdfSigner(sopt);
+var u8arr = await signer.sign(new Uint8Array(pdfBlob.getBytes()));
+// Save the result pdf to some folder
+var fld = DriveApp.getFolderById("a folder's id");
+fld.createFile(Utilities.newBlob(u8arr, "application/pdf").setName("signed_test.pdf"));
+```
+
## Detail of SignOption
-* __p12cert__: string :point_right: A raw data of the certificate
+* __p12cert__: (Uint8Array|ArrayBuffer|string) :point_right: Certificate's data
* __pwd__: string :point_right: The passphrase of the certificate
* __reason__: string :point_right: (Optional) The reason for signing
* __location__: string :point_right: (Optional) Your location
diff --git a/closure/zb-externs.js b/closure/zb-externs.js
new file mode 100644
index 0000000..ab09bbb
--- /dev/null
+++ b/closure/zb-externs.js
@@ -0,0 +1,39 @@
+/**
+ * the base point of x, y is top left corner.
+ * @typedef
+ * {{
+ * x: number,
+ * y: number,
+ * w: number,
+ * h: number,
+ * }}
+ */
+var SignAreaInfo;
+/**
+ * @typedef
+ * {{
+ * area: SignAreaInfo,
+ * pageidx: (number|undefined),
+ * imgData: (Uint8Array|ArrayBuffer|string|undefined),
+ * imgType: (string|undefined),
+ * text: (string|undefined),
+ * fontData: (PDFLib.StandardFonts|Uint8Array|ArrayBuffer|string|undefined),
+ * img: (PDFLib.PDFImage|undefined),
+ * font: (PDFLib.PDFFont|undefined),
+ * }}
+ */
+var SignDrawInfo;
+/**
+ * @typedef
+ * {{
+ * p12cert: (Uint8Array|ArrayBuffer|string),
+ * pwd: string,
+ * reason: (string|undefined),
+ * location: (string|undefined),
+ * contact: (string|undefined),
+ * signdate: (Date|undefined),
+ * signame: (string|undefined),
+ * drawinf: (SignDrawInfo|undefined),
+ * }}
+ */
+var SignOption;
diff --git a/test.html b/test.html
index aaecd2b..72d2977 100644
--- a/test.html
+++ b/test.html
@@ -39,9 +39,8 @@ function testSign(imgdat, imgtyp){
var kf = document.getElementById("kkk").files[0];
readAsArrayBuffer(fil, function(a_pdf){
readAsArrayBuffer(kf, async function(b_kfbuf){
- var b_kfdat = String.fromCharCode.apply(null, new Uint8Array(b_kfbuf));
var b_opt = {
- p12cert: b_kfdat,
+ p12cert: b_kfbuf,
pwd: document.getElementById("pwd").value,
};
if(imgdat){
@@ -56,10 +55,10 @@ function testSign(imgdat, imgtyp){
imgType: imgtyp,
};
}
- var b_signer = new PdfSigner(b_opt);
- var b_blob = await b_signer.sign(a_pdf);
+ var b_signer = new Zga.PdfSigner(b_opt);
+ var b_u8s = await b_signer.sign(a_pdf);
document.getElementById("download").download = "zzzs3.pdf";
- document.getElementById("download").href = window.URL.createObjectURL(b_blob);
+ document.getElementById("download").href = window.URL.createObjectURL(new Blob([b_u8s], {"type" : "application/pdf"}));
document.getElementById("download").click();
});
});
diff --git a/zgapdfsigner.js b/zgapdfsigner.js
index 50c6272..eea2057 100644
--- a/zgapdfsigner.js
+++ b/zgapdfsigner.js
@@ -1,44 +1,8 @@
-/**
- * the base point of x, y is top left corner.
- * @typedef
- * {{
- * x: number,
- * y: number,
- * w: number,
- * h: number,
- * }}
- */
-var SignAreaInfo;
-/**
- * @typedef
- * {{
- * area: SignAreaInfo,
- * pageidx: (number|undefined),
- * imgData: (Uint8Array|ArrayBuffer|string|undefined),
- * imgType: (string|undefined),
- * text: (string|undefined),
- * fontData: (PDFLib.StandardFonts|Uint8Array|ArrayBuffer|string|undefined),
- * img: (PDFLib.PDFImage|undefined),
- * font: (PDFLib.PDFFont|undefined),
- * }}
- */
-var SignDrawInfo;
-/**
- * @typedef
- * {{
- * p12cert: string,
- * pwd: string,
- * reason: (string|undefined),
- * location: (string|undefined),
- * contact: (string|undefined),
- * signdate: (Date|undefined),
- * signame: (string|undefined),
- * drawinf: (SignDrawInfo|undefined),
- * }}
- */
-var SignOption;
+'use strict';
-class PdfSigner {
+globalThis.Zga = {
+
+PdfSigner: class {
/**
* @constructor
* @param {SignOption} signopt
@@ -51,7 +15,7 @@ class PdfSigner {
/**
* @public
* @param {PDFLib.PDFDocument|Uint8Array|ArrayBuffer|string} pdf
- * @return {Blob}
+ * @return {Promise}
*/
async sign(pdf){
/** @type {PDFLib.PDFDocument} */
@@ -74,8 +38,7 @@ class PdfSigner {
this.addSignHolder(pdfdoc);
var uarr = await pdfdoc.save({"useObjectStreams": false});
- // return new Blob([uarr], {"type" : "application/pdf"});
- var pdfstr = String.fromCharCode.apply(null, uarr);
+ var pdfstr = Zga.u8arrToRaw(uarr);
return this.signPdf(pdfstr);
}
@@ -91,7 +54,7 @@ class PdfSigner {
const SIGNATURE_LENGTH = 3322;
/** @const {VisualSignature} */
- const visign = new VisualSignature(this.opt.drawinf);
+ const visign = new Zga.VisualSignature(this.opt.drawinf);
/** @const {PDFLib.PDFRef} */
const strmRef = visign.createStream(pdfdoc, this.opt.signame);
/** @const {PDFLib.PDFPage} */
@@ -118,7 +81,7 @@ class PdfSigner {
"M": PDFLib.PDFString.fromDate(this.opt.signdate),
"Prop_Build": pdfdoc.context.obj({
"App": pdfdoc.context.obj({
- "Name": "ZbPdfSinger",
+ "Name": "ZgaPdfSinger",
}),
}),
};
@@ -167,7 +130,7 @@ class PdfSigner {
/**
* @private
* @param {string} pdfstr
- * @return {Blob}
+ * @return {Uint8Array}
*/
signPdf(pdfstr){
if(!this.opt.signdate){
@@ -200,6 +163,9 @@ class PdfSigner {
// Remove the placeholder signature
pdfstr = pdfstr.slice(0, byteRange[1]) + pdfstr.slice(byteRange[2], byteRange[2] + byteRange[3]);
+ if(typeof this.opt.p12cert !== "string"){
+ this.opt.p12cert = Zga.u8arrToRaw(new Uint8Array(this.opt.p12cert));
+ }
// Convert Buffer P12 to a forge implementation.
var p12Asn1 = forge.asn1.fromDer(this.opt.p12cert);
var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, true, this.opt.pwd);
@@ -271,29 +237,11 @@ class PdfSigner {
// Place it in the document.
pdfstr = pdfstr.slice(0, byteRange[1]) + "<" + sighex + ">" + pdfstr.slice(byteRange[1]);
- return this.rawToBlob(pdfstr, "application/pdf");
+ return Zga.rawToU8arr(pdfstr);
}
+},
- /**
- * @private
- * @param {string} raw
- * @param {string=} typ
- * @return {Blob}
- */
- rawToBlob(raw, typ){
- var arr = new Uint8Array(raw.length);
- for(var i=0; i} */
+ var arr = [];
+ for(var i=0; i