Compare commits

..

3 Commits
2.7.1 ... main

Author SHA1 Message Date
zboris12 0d39f569ae Changed to allow TSA feature in web browser 2024-08-24 12:17:43 +09:00
zboris12 e5372e2652 Added explanation of simulating clearTimeout function. 2024-08-19 21:54:15 +09:00
zboris12 9706bfe31a Improved to support font subsetting and changed to use pdf-fontkit. 2024-08-19 21:33:38 +09:00
11 changed files with 215 additions and 430 deletions

View File

@ -18,9 +18,9 @@ And I use this name to hope the merits from this application will be dedicated t
* A visible signature can be placed on multiple pages. (In the same position) * A visible signature can be placed on multiple pages. (In the same position)
* Sign a pdf and set [DocMDP](https://github.com/zboris12/zgapdfsigner/wiki/API#note). * Sign a pdf and set [DocMDP](https://github.com/zboris12/zgapdfsigner/wiki/API#note).
* Add a new signature to a pdf if it has been signed already. (An incremental update) * Add a new signature to a pdf if it has been signed already. (An incremental update)
* Add a document timestamp from [TSA](https://github.com/zboris12/zgapdfsigner/wiki/API#note). ( :no_entry_sign:__Not__ available in web browser) * Add a document timestamp from [TSA](https://github.com/zboris12/zgapdfsigner/wiki/API#note). ( :no_entry_sign:__Not__ available in web browser :sunflower:)
* Sign a pdf with a timestamp from [TSA](https://github.com/zboris12/zgapdfsigner/wiki/API#note). ( :no_entry_sign:__Not__ available in web browser) * Sign a pdf with a timestamp from [TSA](https://github.com/zboris12/zgapdfsigner/wiki/API#note). ( :no_entry_sign:__Not__ available in web browser :sunflower:)
* Enable signature's [LTV](https://github.com/zboris12/zgapdfsigner/wiki/API#note). ( :no_entry_sign:__Not__ available in web browser) * Enable signature's [LTV](https://github.com/zboris12/zgapdfsigner/wiki/API#note). ( :no_entry_sign:__Not__ available in web browser :sunflower:)
* Set password protection to a pdf. Supported algorithms: * Set password protection to a pdf. Supported algorithms:
* 40bit RC4 Encryption * 40bit RC4 Encryption
* 128bit RC4 Encryption * 128bit RC4 Encryption
@ -33,12 +33,16 @@ And I use this name to hope the merits from this application will be dedicated t
Because of the [CORS](https://github.com/zboris12/zgapdfsigner/wiki/API#note) security restrictions in web browser, Because of the [CORS](https://github.com/zboris12/zgapdfsigner/wiki/API#note) security restrictions in web browser,
signing with a timestamp from [TSA](https://github.com/zboris12/zgapdfsigner/wiki/API#note) or enabling [LTV](https://github.com/zboris12/zgapdfsigner/wiki/API#note) can only be used in [Google Apps Script](https://developers.google.com/apps-script) or [nodejs](https://nodejs.org/). signing with a timestamp from [TSA](https://github.com/zboris12/zgapdfsigner/wiki/API#note) or enabling [LTV](https://github.com/zboris12/zgapdfsigner/wiki/API#note) can only be used in [Google Apps Script](https://developers.google.com/apps-script) or [nodejs](https://nodejs.org/).
:sunflower: However, if you can avoid the [CORS](https://github.com/zboris12/zgapdfsigner/wiki/API#note) security restrictions
by creating your own service or providing a reverse proxy server, these features are also available in web browser.
## The Dependencies ## The Dependencies
* [pdf-lib](https://pdf-lib.js.org/) * [pdf-lib](https://pdf-lib.js.org/)
* [node-forge](https://github.com/digitalbazaar/forge) * [node-forge](https://github.com/digitalbazaar/forge)
* [follow-redirects](https://github.com/follow-redirects/follow-redirects) * [follow-redirects](https://github.com/follow-redirects/follow-redirects)
* [pako](https://github.com/nodeca/pako) - For drawing text
* [pdf-fontkit](https://github.com/znacloud/pdf-fontkit) - For drawing text
## How to use this tool ## How to use this tool
@ -53,9 +57,10 @@ Just import the dependencies and this tool.
``` ```
When drawing text for signature, importing fontkit and pako library is necessary. When drawing text for signature, importing fontkit and pako library is necessary.
```html ```html
<script src="https://unpkg.com/@pdf-lib/fontkit/dist/fontkit.umd.min.js" type="text/javascript"></script> <script src="https://unpkg.com/pdf-fontkit@1.8.9/dist/fontkit.umd.min.js" type="text/javascript"></script>
<script src="https://unpkg.com/pako@1.0.11/dist/pako_inflate.min.js" type="text/javascript"></script> <script src="https://unpkg.com/pako@1.0.11/dist/pako_inflate.min.js" type="text/javascript"></script>
``` ```
Thanks to [znacloud](https://github.com/znacloud/pdf-fontkit) for fixing the font subsetting issue in [@pdf-lib/fontkit](https://github.com/Hopding/fontkit).
### [Google Apps Script](https://developers.google.com/apps-script) ### [Google Apps Script](https://developers.google.com/apps-script)
Load the dependencies and this tool. Load the dependencies and this tool.
@ -65,12 +70,16 @@ function setTimeout(func, sleep){
Utilities.sleep(sleep); Utilities.sleep(sleep);
func(); func();
} }
// Simulate clearTimeout function for pdf-fontkit
function clearTimeout(timeoutID){
// Do nothing
}
// Simulate window for node-forge // Simulate window for node-forge
var window = globalThis; var window = globalThis;
// Load pdf-lib // Load pdf-lib
eval(UrlFetchApp.fetch("https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.min.js").getContentText()); eval(UrlFetchApp.fetch("https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.min.js").getContentText());
// It is necessary for drawing text for signature. // It is necessary for drawing text for signature.
eval(UrlFetchApp.fetch("https://unpkg.com/@pdf-lib/fontkit/dist/fontkit.umd.min.js").getContentText()); eval(UrlFetchApp.fetch("https://unpkg.com/pdf-fontkit@1.8.9/dist/fontkit.umd.min.js").getContentText());
// Load pako, It is necessary for drawing text for signature. // Load pako, It is necessary for drawing text for signature.
eval(UrlFetchApp.fetch("https://unpkg.com/pako@1.0.11/dist/pako_inflate.min.js").getContentText()); eval(UrlFetchApp.fetch("https://unpkg.com/pako@1.0.11/dist/pako_inflate.min.js").getContentText());
// Load node-forge // Load node-forge

View File

@ -9,6 +9,8 @@ else
mkdir ${OUTFLDR} mkdir ${OUTFLDR}
fi fi
VER=$(sed -n -r "s/^.*\"version\": ?\"([0-9.]+)\".*$/\1/p" package.json)
GCCOPT="--charset UTF-8 --compilation_level SIMPLE_OPTIMIZATIONS --warning_level VERBOSE" GCCOPT="--charset UTF-8 --compilation_level SIMPLE_OPTIMIZATIONS --warning_level VERBOSE"
GCCEXT="--externs closure/google-ext.js --externs closure/forge-ext.js --externs closure/pdflib-ext.js --externs closure/zb-externs.js" GCCEXT="--externs closure/google-ext.js --externs closure/forge-ext.js --externs closure/pdflib-ext.js --externs closure/zb-externs.js"
jss="" jss=""
@ -20,7 +22,12 @@ do
if [ "$c" != "#" ] if [ "$c" != "#" ]
then then
outf="${OUTFLDR}/_${js}" outf="${OUTFLDR}/_${js}"
sed -e "s/\/\/Only for nodejs Start\/\//\/*/g" -e "s/\/\/Only for nodejs End\/\//*\//g" "lib/${js}" > "${outf}" if [ "${js}" = "zgaindex.js" ]
then
sed -e "s/\/\/Only for nodejs Start\/\//\/*/g" -e "s/\/\/Only for nodejs End\/\//*\//g" -e "s/ver: \"\"/ver: \"${VER}\"/" "lib/${js}" > "${outf}"
else
sed -e "s/\/\/Only for nodejs Start\/\//\/*/g" -e "s/\/\/Only for nodejs End\/\//*\//g" "lib/${js}" > "${outf}"
fi
if [ $? -eq 0 ] if [ $? -eq 0 ]
then then
echo "Created js file: ${outf}" echo "Created js file: ${outf}"
@ -32,6 +39,7 @@ do
fi fi
fi fi
done <<EOF done <<EOF
zgafetch.js
zgacertsutil.js zgacertsutil.js
zgapdfcryptor.js zgapdfcryptor.js
zgapdfsigner.js zgapdfsigner.js

View File

@ -36,6 +36,7 @@ var SignAreaInfo;
* {{ * {{
* text: string, * text: string,
* fontData: (Array<number>|Uint8Array|ArrayBuffer|string|undefined), * fontData: (Array<number>|Uint8Array|ArrayBuffer|string|undefined),
* subset: (boolean|undefined),
* color: (string|undefined), * color: (string|undefined),
* opacity: (number|undefined), * opacity: (number|undefined),
* blendMode: (string|undefined), * blendMode: (string|undefined),

140
lib/zgafetch.js Normal file
View File

@ -0,0 +1,140 @@
/**
* @param {Object<string, *>} z
*/
function supplyZgaUrlFetch(z){
//Only for nodejs Start//
const m_urlparser = require("url");
const m_h = {
"http:": require('follow-redirects').http,
"https:": require('follow-redirects').https,
};
// @type {boolean}
z.isNode = function(){return this === globalThis.global;}();
//Only for nodejs End//
/** @type {boolean} */
z.isBrowser = function(){return this === globalThis.self;}();
/**
* @param {string} url
* @param {UrlFetchParams} params
* @return {Promise<Uint8Array>}
*/
z.urlFetch = function(url, params){
//Only for nodejs Start//
if(z.isNode){
return new Promise(function(resolve, reject){
// @type {URL}
var opts = m_urlparser.parse(url);
var http = m_h[opts.protocol];
// @type {string|Buffer}
var dat = null;
var encoding = undefined;
opts.method = "GET";
if(params){
if(params.payload instanceof Buffer){
dat = params.payload;
}else if(params.payload instanceof Uint8Array){
dat = Buffer.from(params.payload.buffer);
}else if(params.payload instanceof ArrayBuffer){
dat = Buffer.from(params.payload);
}else{
dat = params.payload;
encoding = "binary";
}
if(params.headers){
opts.headers = params.headers;
}
if(params.method){
opts.method = params.method;
}
if(params.validateHttpsCertificates === false){
opts.rejectUnauthorized = false;
}
}
// @type {http.ClientRequest}
var hreq = http.request(opts, function(a_res){ // @type {http.IncomingMessage} a_res
if(a_res.statusCode !== 200){
var a_err = new Error("Failed to request url. " + url + "\n Status Code: " + a_res.statusCode);
a_res.resume();
throw a_err;
}
// @type {Array<Buffer>}
var a_bufs = [];
var a_bufs_len = 0;
a_res.on("data", function(b_chunk){ // @type {Buffer} b_chunk
a_bufs.push(b_chunk);
a_bufs_len += b_chunk.length;
});
a_res.on("end", function(){
// @type {Buffer}
var b_bdat = Buffer.concat(a_bufs, a_bufs_len);
resolve(b_bdat);
});
});
hreq.on("error", function(a_err){
throw a_err;
});
hreq.end(dat, encoding);
});
}
//Only for nodejs End//
// Google Apps Script
if(globalThis.UrlFetchApp){
return new Promise(function(resolve){
/** @type {GBlob} */
var tblob = UrlFetchApp.fetch(url, params).getBlob();
resolve(new Uint8Array(tblob.getBytes()));
});
}
// browser
if(z.isBrowser && globalThis.self.fetch){
/**
* @return {Promise<Uint8Array>}
*/
var func = async function(){
/** @type {!RequestInit} */
var reqinf = {
method: "GET",
redirect: "follow",
};
if(params){
if(params.payload){
reqinf.body = params.payload;
}
if(params.headers){
reqinf.headers = params.headers;
}
if(params.method){
reqinf.method = params.method;
}
}
/** @type {Response} */
var resp = await fetch(url, reqinf);
if(resp.ok){
/** @type {ArrayBuffer} */
var abdat = await resp.arrayBuffer();
return new Uint8Array(abdat);
}else{
/** @type {string} */
var msg = await resp.text();
throw new Error("Fetch failed." + resp.status + ": " + msg);
}
};
return func();
}
return null;
};
}
//Only for nodejs Start//
if(typeof exports === "object" && typeof module !== "undefined"){
module.exports = supplyZgaUrlFetch;
}
//Only for nodejs End//

View File

@ -5,7 +5,9 @@
*/ */
function genZga(){ function genZga(){
/** @const {Object<string, *>} */ /** @const {Object<string, *>} */
const z = {}; const z = {
ver: "",
};
/** /**
* @param {...string} msg * @param {...string} msg
@ -42,22 +44,6 @@ function genZga(){
return arr; return arr;
}; };
// Google Apps Script
if(globalThis.UrlFetchApp){
/**
* @param {string} url
* @param {UrlFetchParams} params
* @return {Promise<Uint8Array>}
*/
z.urlFetch = function(url, params){
return new Promise(function(resolve){
/** @type {GBlob} */
var tblob = UrlFetchApp.fetch(url, params).getBlob();
resolve(new Uint8Array(tblob.getBytes()));
});
};
}
return z; return z;
} }
@ -68,6 +54,7 @@ if(typeof exports === "object" && typeof module !== "undefined"){
//Only for nodejs End// //Only for nodejs End//
if(!globalThis.Zga){ if(!globalThis.Zga){
globalThis.Zga = genZga(); globalThis.Zga = genZga();
supplyZgaUrlFetch(globalThis.Zga);
supplyZgaCertsChain(globalThis.Zga); supplyZgaCertsChain(globalThis.Zga);
supplyZgaCryptor(globalThis.Zga); supplyZgaCryptor(globalThis.Zga);
supplyZgaSigner(globalThis.Zga); supplyZgaSigner(globalThis.Zga);

3
lib/zganode.d.ts vendored
View File

@ -38,6 +38,7 @@ export type SignAreaInfo = {
export type SignTextInfo = { export type SignTextInfo = {
text: string, text: string,
fontData?: Array<number> | Uint8Array | ArrayBuffer | PDFLib.StandardFonts; fontData?: Array<number> | Uint8Array | ArrayBuffer | PDFLib.StandardFonts;
subset?: boolean;
color?: string; color?: string;
opacity?: number; opacity?: number;
blendMode?: string; blendMode?: string;
@ -112,5 +113,5 @@ export declare class TsaFetcher {
export declare class PdfFonts { export declare class PdfFonts {
private constructor(); private constructor();
static from(pdfdoc: PDFLib.PDFDocument): Promise<PdfFonts>; static from(pdfdoc: PDFLib.PDFDocument): Promise<PdfFonts>;
getEmbeddedFont(fontData?: Array<number> | Uint8Array | ArrayBuffer | PDFLib.StandardFonts): Promise<PDFLib.PDFFont>; getEmbeddedFont(fontData?: Array<number> | Uint8Array | ArrayBuffer | PDFLib.StandardFonts, subset?: boolean): Promise<PDFLib.PDFFont>;
} }

View File

@ -6,71 +6,11 @@ const m_h = {
const z = require("./zgaindex.js"); const z = require("./zgaindex.js");
z.forge = require("node-forge"); z.forge = require("node-forge");
z.PDFLib = require("pdf-lib"); z.PDFLib = require("pdf-lib");
z.fontkit = require("@pdf-lib/fontkit"); // z.fontkit = require("@pdf-lib/fontkit");
z.fontkit = require("pdf-fontkit");
z.pako = require("pako"); z.pako = require("pako");
/**
* @param {string} url
* @param {UrlFetchParams} params
* @return {Promise<Uint8Array>}
*/
z.urlFetch = function(url, params){
return new Promise(function(resolve, reject){
/** @type {URL} */
var opts = m_urlparser.parse(url);
var http = m_h[opts.protocol];
/** @type {string|Buffer} */
var dat = null;
var encoding = undefined;
opts.method = "GET";
if(params){
if(params.payload instanceof Buffer){
dat = params.payload;
}else if(params.payload instanceof Uint8Array){
dat = Buffer.from(params.payload.buffer);
}else if(params.payload instanceof ArrayBuffer){
dat = Buffer.from(params.payload);
}else{
dat = params.payload;
encoding = "binary";
}
if(params.headers){
opts.headers = params.headers;
}
if(params.method){
opts.method = params.method;
}
if(params.validateHttpsCertificates === false){
opts.rejectUnauthorized = false;
}
}
/** @type {http.ClientRequest} */
var hreq = http.request(opts, function(/** @type {http.IncomingMessage} */a_res){
if(a_res.statusCode !== 200){
var a_err = new Error("Failed to request url. " + url + "\n Status Code: " + a_res.statusCode);
a_res.resume();
throw a_err;
}
/** @type {Array<Buffer>} */
var a_bufs = [];
var a_bufs_len = 0;
a_res.on("data", function(/** @type {Buffer} */b_chunk){
a_bufs.push(b_chunk);
a_bufs_len += b_chunk.length;
});
a_res.on("end", function(){
/** @type {Buffer} */
var b_bdat = Buffer.concat(a_bufs, a_bufs_len);
resolve(b_bdat);
});
});
hreq.on("error", function(a_err){
throw a_err;
});
hreq.end(dat, encoding);
});
};
require("./zgafetch.js")(z);
require("./zgacertsutil.js")(z); require("./zgacertsutil.js")(z);
require("./zgapdfcryptor.js")(z); require("./zgapdfcryptor.js")(z);
require("./zgapdfsigner.js")(z); require("./zgapdfsigner.js")(z);

View File

@ -260,6 +260,9 @@ z.PdfSigner = class{
if(!(globalThis.forge || forge)){ if(!(globalThis.forge || forge)){
throw new Error("node-forge is not imported."); throw new Error("node-forge is not imported.");
} }
if(z.ver){
z.log("ZgaPdfSigner Version:", z.ver);
}
/** @type {?TsaServiceInfo} */ /** @type {?TsaServiceInfo} */
var tsainf = null; var tsainf = null;
if(signopt.signdate){ if(signopt.signdate){
@ -273,11 +276,13 @@ z.PdfSigner = class{
} }
if(tsainf){ if(tsainf){
if(!z.urlFetch){ if(!z.urlFetch){
throw new Error("Because of the CORS security restrictions, signing with TSA is not supported in web browser."); // throw new Error("Because of the CORS security restrictions, signing with TSA is not supported in web browser.");
throw new Error("No fetch method found in this environment.");
} }
if(z.TSAURLS[tsainf.url]){ if(z.TSAURLS[tsainf.url]){
Object.assign(tsainf, z.TSAURLS[tsainf.url]); Object.assign(tsainf, z.TSAURLS[tsainf.url]);
}else if(!(new RegExp("^https?://")).test(tsainf.url)){ }else if(!tsainf.url || (!z.isBrowser && !(new RegExp("^https?://")).test(tsainf.url))){
// It may be a relative path in browser environment, so only check in non-browser environment
throw new Error("Unknown tsa data. " + JSON.stringify(tsainf)); throw new Error("Unknown tsa data. " + JSON.stringify(tsainf));
} }
if(!tsainf.len){ if(!tsainf.len){
@ -347,7 +352,7 @@ z.PdfSigner = class{
if(_this.opt.drawinf && _this.opt.drawinf.textInfo && !_this.opt.drawinf.font){ if(_this.opt.drawinf && _this.opt.drawinf.textInfo && !_this.opt.drawinf.font){
_this.fonts = await z.PdfFonts.from(pdfdoc); _this.fonts = await z.PdfFonts.from(pdfdoc);
_this.opt.drawinf.font = await _this.fonts.getEmbeddedFont(_this.opt.drawinf.textInfo.fontData); _this.opt.drawinf.font = await _this.fonts.getEmbeddedFont(_this.opt.drawinf.textInfo.fontData, _this.opt.drawinf.textInfo.subset);
} }
/** @type {forge_cert} */ /** @type {forge_cert} */
@ -1910,12 +1915,16 @@ z.PdfFonts = class{
if(fltr == "/FlateDecode"){ if(fltr == "/FlateDecode"){
fdat = pako.inflate(fdat); fdat = pako.inflate(fdat);
} }
/** @type {PDFLib.CustomFontEmbedder} */ try{
var emdr = await PDFLib.CustomFontEmbedder.for(fontkit, fdat); /** @type {PDFLib.CustomFontEmbedder} */
fonts.push({ var emdr = await PDFLib.CustomFontEmbedder.for(fontkit, fdat);
font: PDFLib.PDFFont.of(poe[0], pdfdoc, emdr), fonts.push({
data: fdat, font: PDFLib.PDFFont.of(poe[0], pdfdoc, emdr),
}); data: fdat,
});
}catch(ex){
z.log(fntnm, ex.message);
}
} }
} }
} }
@ -1929,9 +1938,10 @@ z.PdfFonts = class{
/** /**
* @public * @public
* @param {Array<number>|Uint8Array|ArrayBuffer|string|undefined} fontData * @param {Array<number>|Uint8Array|ArrayBuffer|string|undefined} fontData
* @param {boolean=} subset
* @return {Promise<PDFLib.PDFFont>} * @return {Promise<PDFLib.PDFFont>}
*/ */
async getEmbeddedFont(fontData){ async getEmbeddedFont(fontData, subset){
if(!fontData){ if(!fontData){
if(this.fonts.length){ if(this.fonts.length){
z.log("Use existing default font.", this.fonts[0].font.name); z.log("Use existing default font.", this.fonts[0].font.name);
@ -1946,7 +1956,7 @@ z.PdfFonts = class{
}else{ }else{
/** @type {Uint8Array} */ /** @type {Uint8Array} */
var u8dat = (fontData instanceof Uint8Array) ? fontData : new Uint8Array(fontData); var u8dat = (fontData instanceof Uint8Array) ? fontData : new Uint8Array(fontData);
return await this.getCustomFont(u8dat); return await this.getCustomFont(u8dat, subset || false);
} }
} }
@ -1972,9 +1982,10 @@ z.PdfFonts = class{
/** /**
* @private * @private
* @param {Uint8Array} fontData * @param {Uint8Array} fontData
* @param {boolean} subset
* @return {Promise<PDFLib.PDFFont>} * @return {Promise<PDFLib.PDFFont>}
*/ */
async getCustomFont(fontData){ async getCustomFont(fontData, subset){
/** @type {number} */ /** @type {number} */
var i = 0; var i = 0;
while(i < this.fonts.length){ while(i < this.fonts.length){
@ -1987,7 +1998,7 @@ z.PdfFonts = class{
} }
} }
this.doc.registerFontkit(fontkit); this.doc.registerFontkit(fontkit);
return await this.doc.embedFont(fontData); return await this.doc.embedFont(fontData, {subset});
} }
/** /**
* @private * @private

338
package-lock.json generated
View File

@ -1,31 +1,23 @@
{ {
"name": "zgapdfsigner", "name": "zgapdfsigner",
"version": "2.5.2", "version": "2.7.2",
"lockfileVersion": 2, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "zgapdfsigner", "name": "zgapdfsigner",
"version": "2.5.2", "version": "2.7.2",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@pdf-lib/fontkit": "^1.1.1",
"follow-redirects": "1.15.6", "follow-redirects": "1.15.6",
"node-forge": "1.3.1", "node-forge": "1.3.1",
"pdf-fontkit": "1.8.9",
"pdf-lib": "1.17.1" "pdf-lib": "1.17.1"
}, },
"devDependencies": { "devDependencies": {
"google-closure-compiler": "^20231112.0.0" "google-closure-compiler": "^20231112.0.0"
} }
}, },
"node_modules/@pdf-lib/fontkit": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@pdf-lib/fontkit/-/fontkit-1.1.1.tgz",
"integrity": "sha512-KjMd7grNapIWS/Dm0gvfHEilSyAmeLvrEGVcqLGi0VYebuqqzTbgF29efCx7tvx+IEbG3zQciRSWl3GkUSvjZg==",
"dependencies": {
"pako": "^1.0.6"
}
},
"node_modules/@pdf-lib/standard-fonts": { "node_modules/@pdf-lib/standard-fonts": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
@ -181,35 +173,6 @@
"integrity": "sha512-E45cJD6/xLJlL8pL6HEoxu8nEKp87CnrojUK0UuHiT7ZjCsrJfR4WhZwNNCq2+/6gYD9unGgMsunV4DDtBbvaA==", "integrity": "sha512-E45cJD6/xLJlL8pL6HEoxu8nEKp87CnrojUK0UuHiT7ZjCsrJfR4WhZwNNCq2+/6gYD9unGgMsunV4DDtBbvaA==",
"dev": true "dev": true
}, },
"node_modules/google-closure-compiler-linux": {
"version": "20231112.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20231112.0.0.tgz",
"integrity": "sha512-qi2DbqQ+OuZ4Mcp1EttmL4j3oqvXLPl8XREekkfdV651PXBNenoBG6EnzQIius7ESYVgmpbQE4Pw2wNhPudBBQ==",
"cpu": [
"x32",
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/google-closure-compiler-osx": {
"version": "20231112.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20231112.0.0.tgz",
"integrity": "sha512-gNnlnVH4rVO5TyDhvqELzRc9Oydaxincj0QLsAQQkM0btBTUEEyFL1ACT00RgJKxrCTb5Lfa83DfU8ICJi5Ptw==",
"cpu": [
"x32",
"x64",
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
]
},
"node_modules/google-closure-compiler-windows": { "node_modules/google-closure-compiler-windows": {
"version": "20231112.0.0", "version": "20231112.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20231112.0.0.tgz", "resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20231112.0.0.tgz",
@ -267,6 +230,14 @@
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
}, },
"node_modules/pdf-fontkit": {
"version": "1.8.9",
"resolved": "https://registry.npmjs.org/pdf-fontkit/-/pdf-fontkit-1.8.9.tgz",
"integrity": "sha512-TTq+umfhlFjUuQYOq6dCKT/wLslCrX4zVr5gqrIvrGHfo+vJ3ETapZTb4YLOCErohX7pF+HxlXSZuiToSRhNmA==",
"dependencies": {
"pako": "^1.0.6"
}
},
"node_modules/pdf-lib": { "node_modules/pdf-lib": {
"version": "1.17.1", "version": "1.17.1",
"resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz", "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
@ -387,290 +358,5 @@
"source-map": "^0.5.1" "source-map": "^0.5.1"
} }
} }
},
"dependencies": {
"@pdf-lib/fontkit": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@pdf-lib/fontkit/-/fontkit-1.1.1.tgz",
"integrity": "sha512-KjMd7grNapIWS/Dm0gvfHEilSyAmeLvrEGVcqLGi0VYebuqqzTbgF29efCx7tvx+IEbG3zQciRSWl3GkUSvjZg==",
"requires": {
"pako": "^1.0.6"
}
},
"@pdf-lib/standard-fonts": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
"integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
"requires": {
"pako": "^1.0.6"
}
},
"@pdf-lib/upng": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
"integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
"requires": {
"pako": "^1.0.10"
}
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"dev": true
},
"clone-buffer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
"integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==",
"dev": true
},
"clone-stats": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
"integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
"dev": true
},
"cloneable-readable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
"integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
"dev": true,
"requires": {
"inherits": "^2.0.1",
"process-nextick-args": "^2.0.0",
"readable-stream": "^2.3.5"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"dev": true
},
"follow-redirects": {
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
},
"google-closure-compiler": {
"version": "20231112.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20231112.0.0.tgz",
"integrity": "sha512-C/MPRThIxRAFomGhpEwXyVcWRIVnmqGraJ5BTJ+EQcfAiPNBvl+Q5nKU2J/lICPcx+YQ+3c+FJ/gBJsTXPjcwg==",
"dev": true,
"requires": {
"chalk": "4.x",
"google-closure-compiler-java": "^20231112.0.0",
"google-closure-compiler-linux": "^20231112.0.0",
"google-closure-compiler-osx": "^20231112.0.0",
"google-closure-compiler-windows": "^20231112.0.0",
"minimist": "1.x",
"vinyl": "2.x",
"vinyl-sourcemaps-apply": "^0.2.0"
}
},
"google-closure-compiler-java": {
"version": "20231112.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20231112.0.0.tgz",
"integrity": "sha512-E45cJD6/xLJlL8pL6HEoxu8nEKp87CnrojUK0UuHiT7ZjCsrJfR4WhZwNNCq2+/6gYD9unGgMsunV4DDtBbvaA==",
"dev": true
},
"google-closure-compiler-linux": {
"version": "20231112.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20231112.0.0.tgz",
"integrity": "sha512-qi2DbqQ+OuZ4Mcp1EttmL4j3oqvXLPl8XREekkfdV651PXBNenoBG6EnzQIius7ESYVgmpbQE4Pw2wNhPudBBQ==",
"dev": true,
"optional": true
},
"google-closure-compiler-osx": {
"version": "20231112.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20231112.0.0.tgz",
"integrity": "sha512-gNnlnVH4rVO5TyDhvqELzRc9Oydaxincj0QLsAQQkM0btBTUEEyFL1ACT00RgJKxrCTb5Lfa83DfU8ICJi5Ptw==",
"dev": true,
"optional": true
},
"google-closure-compiler-windows": {
"version": "20231112.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20231112.0.0.tgz",
"integrity": "sha512-wbN5EOCGz53HVENVtOEO1brn/G3ZmCV1ULiJljNuASQc62vQ36QHA6XnAZOAGTEpAoMnYRv3dtXtBKd07wBdsA==",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"dev": true
},
"minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true
},
"node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA=="
},
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"pdf-lib": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
"integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==",
"requires": {
"@pdf-lib/standard-fonts": "^1.0.0",
"@pdf-lib/upng": "^1.0.1",
"pako": "^1.0.11",
"tslib": "^1.11.1"
}
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
"dev": true
},
"replace-ext": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
"integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
"dev": true
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"dev": true
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
"vinyl": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
"integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
"dev": true,
"requires": {
"clone": "^2.1.1",
"clone-buffer": "^1.0.0",
"clone-stats": "^1.0.0",
"cloneable-readable": "^1.0.0",
"remove-trailing-separator": "^1.0.1",
"replace-ext": "^1.0.0"
}
},
"vinyl-sourcemaps-apply": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
"integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==",
"dev": true,
"requires": {
"source-map": "^0.5.1"
}
}
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "zgapdfsigner", "name": "zgapdfsigner",
"version": "2.7.1", "version": "2.7.3",
"author": "zboris12", "author": "zboris12",
"description": "A javascript tool to sign a pdf or set protection to a pdf in web browser, Google Apps Script and nodejs.", "description": "A javascript tool to sign a pdf or set protection to a pdf in web browser, Google Apps Script and nodejs.",
"homepage": "https://github.com/zboris12/zgapdfsigner", "homepage": "https://github.com/zboris12/zgapdfsigner",
@ -14,6 +14,7 @@
}, },
"license": "MIT", "license": "MIT",
"main": "lib/zganode.js", "main": "lib/zganode.js",
"unpkg": "dist/zgapdfsigner.min.js",
"files": [ "files": [
"dist/*.min.js", "dist/*.min.js",
"lib/*.d.ts", "lib/*.d.ts",
@ -34,9 +35,9 @@
"test": "node test4node.js ${pfxpwd}" "test": "node test4node.js ${pfxpwd}"
}, },
"dependencies": { "dependencies": {
"@pdf-lib/fontkit": "^1.1.1",
"follow-redirects": "1.15.6", "follow-redirects": "1.15.6",
"node-forge": "1.3.1", "node-forge": "1.3.1",
"pdf-fontkit": "1.8.9",
"pdf-lib": "1.17.1" "pdf-lib": "1.17.1"
}, },
"devDependencies": { "devDependencies": {

View File

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> Test for ZgaPdfSigner </title> <title> Test for ZgaPdfSigner </title>
<script src="https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.min.js" type="text/javascript"></script> <script src="https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.min.js" type="text/javascript"></script>
<script src="https://unpkg.com/@pdf-lib/fontkit/dist/fontkit.umd.min.js" type="text/javascript"></script> <script src="https://unpkg.com/pdf-fontkit@1.8.9/dist/fontkit.umd.min.js" type="text/javascript"></script>
<script src="https://unpkg.com/pako@1.0.11/dist/pako_inflate.min.js" type="text/javascript"></script> <script src="https://unpkg.com/pako@1.0.11/dist/pako_inflate.min.js" type="text/javascript"></script>
<script src="https://unpkg.com/node-forge@1.3.1/dist/forge.min.js" type="text/javascript"></script> <script src="https://unpkg.com/node-forge@1.3.1/dist/forge.min.js" type="text/javascript"></script>
<script src="dist/zgapdfsigner.min.js" type="text/javascript"></script> <script src="dist/zgapdfsigner.min.js" type="text/javascript"></script>
@ -103,6 +103,7 @@ async function testMe(){
textInfo: txt ? { textInfo: txt ? {
text: txt, text: txt,
fontData: font, fontData: font,
subset: true,
color: "f00", color: "f00",
size: 16, size: 16,
align: 2, align: 2,