diff --git a/.gitignore b/.gitignore index 8325a2a..cedbc3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -dist/ *.ttf *.pdf Thumbs.db diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..e876dd2 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,3 @@ +declare const decryptPDF: (pdf: string | Uint8Array | ArrayBuffer, ownerPassword: string) => Promise; + +export { decryptPDF }; diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..181ea0f --- /dev/null +++ b/dist/index.js @@ -0,0 +1,1356 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var __async = (__this, __arguments, generator) => { + return new Promise((resolve, reject) => { + var fulfilled = (value) => { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + }; + var rejected = (value) => { + try { + step(generator.throw(value)); + } catch (e) { + reject(e); + } + }; + var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); + step((generator = generator.apply(__this, __arguments)).next()); + }); +}; + +// src/index.ts +var src_exports = {}; +__export(src_exports, { + decryptPDF: () => decryptPDF +}); +module.exports = __toCommonJS(src_exports); + +// src/pdf-lib_patch.ts +var import_pdf_lib2 = require("pdf-lib"); +var import_pdf_lib3 = require("pdf-lib"); +var import_pdf_lib4 = require("pdf-lib"); + +// src/PDFSecurity.ts +var CryptoJS = __toESM(require("crypto-js")); +var import_pdf_lib = require("pdf-lib"); + +// src/utils.ts +var buffer2Str = (b, pos, len) => { + const _str = []; + const _pos = pos || 0; + const _len = len || b.length; + for (let i = 0; i < _len; i++) { + if (typeof b[_pos + i] === "number") { + _str.push(String.fromCodePoint(b[_pos + i])); + } + } + return _str.join(""); +}; +var buffer2Hex = (b, pos, len) => { + const _str = []; + const _pos = pos || 0; + const _len = len || b.length; + for (let i = 0; i < _len; i++) { + if (typeof b[_pos + i] === "number") { + _str.push(b[_pos + i].toString(16).padStart(2, "0")); + } + } + return _str.join(""); +}; + +// src/PDFSecurity.ts +var PDFSecurity = class _PDFSecurity { + /* + ID file is an array of two byte-string constituing + a file identifier + + Required if Encrypt entry is present in Trailer + Doesn't really matter what it is as long as it is + consistently used. + */ + static generateFileID(info) { + return wordArrayToBuffer(CryptoJS.MD5(info.toString())); + } + static generateRandomWordArray(bytes) { + return CryptoJS.lib.WordArray.random(bytes); + } + static create(document, options = {}) { + return new _PDFSecurity(document, options); + } + static decrypter(encryptionDic, context, password, reqPermission) { + const filter = encryptionDic.get(import_pdf_lib.PDFName.of("Filter")); + if (!(filter instanceof import_pdf_lib.PDFName) || filter.toString() !== "/Standard") { + throw new Error(`Unsupport security handler. ${filter == null ? void 0 : filter.toString()}`); + } + const keylength = encryptionDic.get(import_pdf_lib.PDFName.of("Length")); + if (!(keylength instanceof import_pdf_lib.PDFNumber)) { + throw new Error(`Unsupport Key length`); + } + const version = encryptionDic.get(import_pdf_lib.PDFName.of("V")); + if (!(version instanceof import_pdf_lib.PDFNumber) || version.asNumber() <= 0 || version.asNumber() === 3 || version.asNumber() > 6) { + throw new Error(`Unsupport encrypt version.`); + } + const permission = encryptionDic.get(import_pdf_lib.PDFName.of("P")); + if (!(permission instanceof import_pdf_lib.PDFNumber)) { + throw new Error(`Permision noentry.`); + } + const revision = encryptionDic.get(import_pdf_lib.PDFName.of("R")); + if (!(revision instanceof import_pdf_lib.PDFNumber) || revision.asNumber() < 2 || revision.asNumber() > 6) { + throw new Error(`Unsupport revesion.`); + } + if (!(context.trailerInfo.ID instanceof import_pdf_lib.PDFArray) || !context.trailerInfo.ID.asArray()[0]) { + throw new Error(`DocumentID undefined.`); + } + const documentID = context.trailerInfo.ID.asArray()[0]; + if (!(documentID instanceof import_pdf_lib.PDFHexString)) { + throw new Error(`DocumentID undefined.`); + } + const ownerPasswordValue = encryptionDic.get(import_pdf_lib.PDFName.of("O")); + if (!(ownerPasswordValue instanceof import_pdf_lib.PDFHexString) && !(ownerPasswordValue instanceof import_pdf_lib.PDFString)) { + throw new Error("O notentry"); + } + const ownerKey = encryptionDic.get(import_pdf_lib.PDFName.of("OE")); + if (version.asNumber() === 5 && !(ownerKey instanceof import_pdf_lib.PDFHexString) && !(ownerKey instanceof import_pdf_lib.PDFString)) { + throw new Error("OE notentry"); + } + const userPasswordValue = encryptionDic.get(import_pdf_lib.PDFName.of("U")); + if (!(userPasswordValue instanceof import_pdf_lib.PDFHexString) && !(userPasswordValue instanceof import_pdf_lib.PDFString)) { + throw new Error("U notentry"); + } + const userKey = encryptionDic.get(import_pdf_lib.PDFName.of("UE")); + if (version.asNumber() === 5 && !(userKey instanceof import_pdf_lib.PDFHexString) && !(userKey instanceof import_pdf_lib.PDFString)) { + throw new Error("OE notentry"); + } + const perms = encryptionDic.get(import_pdf_lib.PDFName.of("Perms")); + if (version.asNumber() === 5 && !(perms instanceof import_pdf_lib.PDFHexString) && !(perms instanceof import_pdf_lib.PDFString)) { + throw new Error("OE notentry"); + } + const encryptMetadataEntry = encryptionDic.get(import_pdf_lib.PDFName.of("EncryptMetadata")); + const encryptMetadata = encryptMetadataEntry instanceof import_pdf_lib.PDFBool ? encryptMetadataEntry.asBoolean() : true; + let passwordCheck = "N"; + const ownerPasswordKey = checkOwnerpassword({ + version: version.asNumber(), + documentID: documentID.asBytes(), + encryptMetadata, + securityRevision: revision.asNumber(), + keyLength: keylength.asNumber(), + permissionNo: permission.asNumber(), + ownerPassword: password || "", + O: ownerPasswordValue.asBytes(), + U: userPasswordValue.asBytes(), + OE: ownerKey == null ? void 0 : ownerKey.asBytes(), + Perms: perms == null ? void 0 : perms.asBytes(), + P: permission.asNumber() + }); + if (ownerPasswordKey) { + passwordCheck = "O"; + } + const userPasswordKey = checkUserpassword({ + version: version.asNumber(), + documentID: documentID.asBytes(), + encryptMetadata, + securityRevision: revision.asNumber(), + keyLength: keylength.asNumber(), + permissionNo: permission.asNumber(), + userPassword: password || "", + O: ownerPasswordValue.asBytes(), + U: userPasswordValue.asBytes(), + UE: userKey == null ? void 0 : userKey.asBytes(), + Perms: perms == null ? void 0 : perms.asBytes(), + P: permission.asNumber() + }); + if (passwordCheck !== "O" && userPasswordKey) { + passwordCheck = "U"; + } + if (ownerPasswordKey && passwordCheck === "O") { + return { + decrypt: getDecryptFn(version.asNumber(), ownerPasswordKey, keylength.asNumber()), + reEncrypt: (obj, gen) => { + return _getEncryptFn(obj, gen, version.asNumber(), keylength.asNumber(), ownerPasswordKey); + } + }; + } else if (userPasswordKey && passwordCheck === "U") { + if (passwordCheck === "U") { + if (reqPermission) { + const permissionNum = permission.asNumber(); + let reject = false; + if (reqPermission.printing) { + if (revision.asNumber() <= 2) { + if (!(permissionNum & 4)) { + reject = true; + } + } else { + if (reqPermission.printing === "lowResolution" && !(permissionNum & 4)) { + reject = true; + } + if (reqPermission.printing === "highResolution" && !(permissionNum & 2052)) { + reject = true; + } + } + } + if (reqPermission.modifying && !(permissionNum & 8)) { + reject = true; + } + if (reqPermission.copying && !(permissionNum & 16)) { + reject = true; + } + if (reqPermission.annotating && !(permissionNum & 32)) { + reject = true; + } + if (reqPermission.fillingForms && !(permissionNum & 64)) { + reject = true; + } + if (reqPermission.contentAccessibility && !(permissionNum & 128)) { + reject = true; + } + if (reqPermission.documentAssembly && !(permissionNum & 256)) { + reject = true; + } + if (!reject) { + return { + decrypt: getDecryptFn(version.asNumber(), userPasswordKey, keylength.asNumber()), + reEncrypt: (obj, gen) => { + return _getEncryptFn(obj, gen, version.asNumber(), keylength.asNumber(), userPasswordKey); + } + }; + } + } + } + } + throw new Error(`Document restriction permission denied.`); + } + constructor(document, options = {}) { + if (!options.ownerPassword && !options.userPassword) { + throw new Error("None of owner password and user password is defined."); + } + this.document = document; + this._setupEncryption(options); + } + /* + Handle all encryption process and give back + EncryptionDictionary that is required + to be plugged into Trailer of the PDF + */ + _setupEncryption(options) { + switch (options.pdfVersion) { + case "1.4": + case "1.5": + this.version = 2; + break; + case "1.6": + case "1.7": + this.version = 4; + break; + case "1.7ext3": + this.version = 5; + break; + case "2.0": + this.version = 5; + this.revesion = 6; + break; + default: + this.version = 1; + break; + } + switch (this.version) { + case 1: + case 2: + case 4: + this.dictionary = this._setupEncryptionV1V2V4(this.version, options); + break; + } + } + _setupEncryptionV1V2V4(v, options) { + const encDict = { + Filter: "Standard" + }; + let r; + let permissions; + switch (v) { + case 1: + r = 2; + this.keyBits = 40; + permissions = getPermissionsR2(options.permissions); + break; + case 2: + r = 3; + this.keyBits = 128; + permissions = getPermissionsR3(options.permissions); + break; + case 4: + r = 4; + this.keyBits = 128; + permissions = getPermissionsR3(options.permissions); + break; + default: + throw new Error("Unknown v value"); + } + const paddedUserPassword = processPasswordR2R3R4( + options.userPassword + ); + const paddedOwnerPassword = options.ownerPassword ? processPasswordR2R3R4(options.ownerPassword) : paddedUserPassword; + const ownerPasswordEntry = getOwnerPasswordR2R3R4( + r, + this.keyBits, + paddedUserPassword, + paddedOwnerPassword + ); + this.encryptionKey = getEncryptionKeyR2R3R4( + r, + this.keyBits, + this.document._id, + paddedUserPassword, + ownerPasswordEntry, + permissions + ); + let userPasswordEntry; + if (r === 2) { + userPasswordEntry = getUserPasswordR2(this.encryptionKey); + } else { + userPasswordEntry = getUserPasswordR3R4( + this.document._id, + this.encryptionKey + ); + } + encDict.V = v; + if (v >= 2) { + encDict.Length = this.keyBits; + } + if (v === 4) { + encDict.CF = { + StdCF: { + AuthEvent: "DocOpen", + CFM: "AESV2", + Length: this.keyBits / 8 + } + }; + encDict.StmF = "StdCF"; + encDict.StrF = "StdCF"; + } + encDict.R = r; + encDict.O = import_pdf_lib.PDFHexString.of(buffer2Hex(wordArrayToBuffer(ownerPasswordEntry))); + encDict.U = import_pdf_lib.PDFHexString.of(buffer2Hex(wordArrayToBuffer(userPasswordEntry))); + encDict.P = permissions; + return encDict; + } + getEncryptFn(obj, gen) { + return _getEncryptFn(obj, gen, this.version, this.keyBits, this.encryptionKey); + } +}; +var getPermissionsR2 = (permissionObject = {}) => { + let permissions = 4294967232 >> 0; + if (permissionObject.printing) { + permissions |= 4; + } + if (permissionObject.modifying) { + permissions |= 8; + } + if (permissionObject.copying) { + permissions |= 16; + } + if (permissionObject.annotating) { + permissions |= 32; + } + return permissions; +}; +var getPermissionsR3 = (permissionObject = {}) => { + let permissions = 4294963392 >> 0; + if (permissionObject.printing === "lowResolution" || permissionObject.printing) { + permissions |= 4; + } + if (permissionObject.printing === "highResolution") { + permissions |= 2052; + } + if (permissionObject.modifying) { + permissions |= 8; + } + if (permissionObject.copying) { + permissions |= 16; + } + if (permissionObject.annotating) { + permissions |= 32; + } + if (permissionObject.fillingForms) { + permissions |= 256; + } + if (permissionObject.contentAccessibility) { + permissions |= 512; + } + if (permissionObject.documentAssembly) { + permissions |= 1024; + } + return permissions; +}; +var getUserPasswordR2 = (encryptionKey) => CryptoJS.RC4.encrypt(processPasswordR2R3R4(), encryptionKey).ciphertext; +var getUserPasswordR3R4 = (documentId, encryptionKey) => { + const key = encryptionKey.clone(); + let cipher = CryptoJS.MD5( + processPasswordR2R3R4().concat( + CryptoJS.lib.WordArray.create(documentId) + ) + ); + for (let i = 0; i < 20; i++) { + const xorRound = Math.ceil(key.sigBytes / 4); + for (let j = 0; j < xorRound; j++) { + key.words[j] = encryptionKey.words[j] ^ (i | i << 8 | i << 16 | i << 24); + } + cipher = CryptoJS.RC4.encrypt(cipher, key).ciphertext; + } + return cipher.concat( + CryptoJS.lib.WordArray.create(null, 16) + ); +}; +var getOwnerPasswordR2R3R4 = (r, keyBits, paddedUserPassword, paddedOwnerPassword) => { + let digest = paddedOwnerPassword; + let round = r >= 3 ? 51 : 1; + for (let i = 0; i < round; i++) { + digest = CryptoJS.MD5(digest); + } + const key = digest.clone(); + key.sigBytes = keyBits / 8; + let cipher = paddedUserPassword; + round = r >= 3 ? 20 : 1; + for (let i = 0; i < round; i++) { + const xorRound = Math.ceil(key.sigBytes / 4); + for (let j = 0; j < xorRound; j++) { + key.words[j] = digest.words[j] ^ (i | i << 8 | i << 16 | i << 24); + } + cipher = CryptoJS.RC4.encrypt(cipher, key).ciphertext; + } + return cipher; +}; +var decryptOpram = (r, keyBits, O, paddedOwnerPassword) => { + let digest = paddedOwnerPassword; + let round = r >= 3 ? 51 : 1; + for (let i = 0; i < round; i++) { + digest = CryptoJS.MD5(digest); + } + const key = digest.clone(); + key.sigBytes = keyBits / 8; + let cipher = O; + round = r >= 3 ? 20 : 1; + for (let i = 0; i < round; i++) { + const xorRound = Math.ceil(key.sigBytes / 4); + for (let j = 0; j < xorRound; j++) { + key.words[j] = digest.words[j] ^ (i | i << 8 | i << 16 | i << 24); + } + const pram = CryptoJS.lib.CipherParams.create({ + ciphertext: cipher + }); + cipher = CryptoJS.RC4.decrypt(pram, key); + } + return cipher; +}; +var getEncryptionKeyR2R3R4 = (r, keyBits, documentId, paddedUserPassword, ownerPasswordEntry, permissions, encryptMetadata = true) => { + let key = paddedUserPassword.clone().concat(ownerPasswordEntry).concat(CryptoJS.lib.WordArray.create([lsbFirstWord(permissions)], 4)).concat(CryptoJS.lib.WordArray.create(documentId)); + if (r === 4 && !encryptMetadata) { + key.concat(CryptoJS.lib.WordArray.create([4294967295])); + } + const round = r >= 3 ? 51 : 1; + for (let i = 0; i < round; i++) { + key = CryptoJS.MD5(key); + key.sigBytes = keyBits / 8; + } + return key; +}; +var processPasswordR2R3R4 = (password = "") => { + const out = new Uint8Array(32); + const length = password.length; + let index = 0; + while (index < length && index < 32) { + const code = password.charCodeAt(index); + if (code > 255) { + throw new Error("Password contains one or more invalid characters."); + } + out[index] = code; + index++; + } + while (index < 32) { + out[index] = PASSWORD_PADDING[index - length]; + index++; + } + return CryptoJS.lib.WordArray.create(out); +}; +var lsbFirstWord = (data) => (data & 255) << 24 | (data & 65280) << 8 | data >> 8 & 65280 | data >> 24 & 255; +var wordArrayToBuffer = (wordArray) => { + const byteArray = []; + for (let i = 0; i < wordArray.sigBytes; i++) { + byteArray.push( + wordArray.words[Math.floor(i / 4)] >> 8 * (3 - i % 4) & 255 + ); + } + return Uint8Array.from(byteArray); +}; +var checkUserpassword = (pram) => { + if (pram.version <= 4) { + if (pram.securityRevision === 2 || pram.securityRevision === 3 || pram.securityRevision === 4) { + const paddedUserPassword = processPasswordR2R3R4( + pram.userPassword + ); + const userAuth = userPasswordAuthV4({ + securityRevision: pram.securityRevision, + keyLength: pram.keyLength, + paddedUserPassword, + permissionNo: pram.permissionNo, + documentID: pram.documentID, + encryptMetadata: pram.encryptMetadata, + O: pram.O + }); + if (pram.U.subarray(0, 16).toString() === userAuth.U.subarray(0, 16).toString()) { + return userAuth.key; + } + return; + } + } else if (pram.version === 5) { + return; + } +}; +var userPasswordAuthV4 = (pram) => { + const encryptionKey = getEncryptionKeyR2R3R4( + pram.securityRevision, + pram.keyLength, + pram.documentID, + pram.paddedUserPassword, + CryptoJS.lib.WordArray.create(pram.O), + pram.permissionNo, + pram.securityRevision === 4 ? pram.encryptMetadata : true + ); + let userPasswordEntry; + if (pram.securityRevision === 2) { + userPasswordEntry = getUserPasswordR2(encryptionKey); + } else { + userPasswordEntry = getUserPasswordR3R4( + pram.documentID, + encryptionKey + ); + } + return { U: wordArrayToBuffer(userPasswordEntry), key: encryptionKey }; +}; +var checkOwnerpassword = (pram) => { + if (pram.version <= 4) { + if (pram.securityRevision === 2 || pram.securityRevision === 3 || pram.securityRevision === 4) { + const paddedOwnerPassword = processPasswordR2R3R4(pram.ownerPassword); + const decryptedUserpassword = decryptOpram(pram.securityRevision, pram.keyLength, CryptoJS.lib.WordArray.create(pram.O), paddedOwnerPassword); + const userAuth = userPasswordAuthV4({ + securityRevision: pram.securityRevision, + keyLength: pram.keyLength, + paddedUserPassword: decryptedUserpassword, + permissionNo: pram.permissionNo, + documentID: pram.documentID, + encryptMetadata: pram.encryptMetadata, + O: pram.O + }); + if (pram.U.subarray(0, 16).toString() === userAuth.U.subarray(0, 16).toString()) { + return userAuth.key; + } + return; + } + } else if (pram.version === 5) { + return; + } +}; +var getDecryptFn = (version, encryptionKey, keyBits) => { + return (encData, objectNumber, generetionNumber) => { + const obj = objectNumber; + const gen = generetionNumber; + let digest; + let key = CryptoJS.lib.WordArray.create(); + if (version < 5) { + digest = encryptionKey.clone().concat( + CryptoJS.lib.WordArray.create( + [ + (obj & 255) << 24 | (obj & 65280) << 8 | obj >> 8 & 65280 | gen & 255, + (gen & 65280) << 16 + ], + 5 + ) + ); + if (version === 1 || version === 2) { + key = CryptoJS.MD5(digest); + key.sigBytes = Math.min(16, keyBits / 8 + 5); + const pram2 = CryptoJS.lib.CipherParams.create({ + ciphertext: CryptoJS.lib.WordArray.create(encData) + }); + return wordArrayToBuffer(CryptoJS.RC4.decrypt(pram2, key)); + } + if (version === 4) { + key = CryptoJS.MD5( + digest.concat(CryptoJS.lib.WordArray.create([1933667412], 4)) + ); + } + } else if (version === 5) { + key = encryptionKey; + } else { + throw new Error("Unknown V value"); + } + const pram = CryptoJS.lib.CipherParams.create({ + ciphertext: CryptoJS.lib.WordArray.create(encData.subarray(16)) + }); + const X = CryptoJS.AES.decrypt(pram, key, { "iv": CryptoJS.lib.WordArray.create(encData.subarray(0, 16)) }); + return wordArrayToBuffer(X); + }; +}; +var _getEncryptFn = (obj, gen, version, keyBits, encryptionKey) => { + let digest; + let key; + if (version < 5) { + digest = encryptionKey.clone().concat( + CryptoJS.lib.WordArray.create( + [ + (obj & 255) << 24 | (obj & 65280) << 8 | obj >> 8 & 65280 | gen & 255, + (gen & 65280) << 16 + ], + 5 + ) + ); + if (version === 1 || version === 2) { + key = CryptoJS.MD5(digest); + key.sigBytes = Math.min(16, keyBits / 8 + 5); + return (buffer) => wordArrayToBuffer( + CryptoJS.RC4.encrypt( + CryptoJS.lib.WordArray.create(buffer), + key + ).ciphertext + ); + } + if (version === 4) { + key = CryptoJS.MD5( + digest.concat(CryptoJS.lib.WordArray.create([1933667412], 4)) + ); + } + } else if (version === 5) { + key = encryptionKey; + } else { + throw new Error("Unknown V value"); + } + const iv = PDFSecurity.generateRandomWordArray(16); + const options = { + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7, + iv + }; + return (buffer) => wordArrayToBuffer( + iv.clone().concat( + CryptoJS.AES.encrypt( + CryptoJS.lib.WordArray.create(buffer), + key, + options + ).ciphertext + ) + ); +}; +var PASSWORD_PADDING = [ + 40, + 191, + 78, + 94, + 78, + 117, + 138, + 65, + 100, + 0, + 78, + 86, + 255, + 250, + 1, + 8, + 46, + 46, + 0, + 182, + 208, + 104, + 62, + 128, + 47, + 12, + 169, + 254, + 100, + 83, + 105, + 122 +]; + +// src/pdf-lib_patch.ts +var import_pdf_lib5 = require("pdf-lib"); +var PDFDocument = import_pdf_lib5.PDFDocument; +var pdf_lib_Patch = { + PDFString_SupportUTF16: (_PDFString) => { + _PDFString.prototype.sizeInBytes = function() { + return stringEncode(this.value, this._noEncode).length + 2; + }; + _PDFString.prototype.copyBytesInto = function(buffer, offset) { + buffer[offset++] = import_pdf_lib3.CharCodes.LeftParen; + offset += copyStringIntoBuffer(this.value, buffer, offset, this._noEncode); + buffer[offset++] = import_pdf_lib3.CharCodes.RightParen; + return this.sizeInBytes(); + }; + }, + _BaseParserPatch: (_bytes) => { + _bytes.moveTOP = function() { + this.line = 0; + this.column = 0; + this.idx = 0; + }; + _bytes.moveEND = function() { + while (!this.done()) { + this.next(); + } + }; + _bytes.prev = function() { + const byte = this.bytes[this.idx--]; + if (byte === import_pdf_lib3.CharCodes.Newline) { + this.line -= 1; + this.column = 0; + } else { + this.column -= 1; + } + return byte; + }; + }, + SupportEncrypt: (_PDFParser, _PDFDocument3, _PDFXRefStreamParser) => { + _PDFParser.prototype.parseStartxref = function(endOffset) { + this.bytes.moveTo(endOffset); + let offset = this.bytes.offset(); + while (offset > 0) { + this.bytes.prev(); + offset = this.bytes.offset(); + const trailer = this.matchKeyword(Keywords.startxref); + if (!trailer) { + this.bytes.moveTo(offset); + } else { + offset = this.bytes.offset(); + this.skipWhitespaceAndComments(); + const xrefoffset = this.parseRawInt(); + this.skipWhitespace(); + this.matchKeyword(Keywords.eof); + this.bytes.moveTo(offset - Keywords.startxref.length); + return xrefoffset; + } + } + }; + _PDFParser.prototype.parseTrailer = function(endOffset) { + this.bytes.moveTo(endOffset); + let offset = this.bytes.offset(); + while (offset > 0 && !this.bytes.done()) { + this.bytes.next(); + offset = this.bytes.offset(); + const trailer = this.matchKeyword(Keywords.trailer); + if (!trailer) { + this.bytes.moveTo(offset); + } else { + offset = this.bytes.offset(); + this.skipWhitespaceAndComments(); + const dict = this.parseDict(); + this.bytes.moveTo(offset - Keywords.trailer.length); + return { + Root: dict.get(import_pdf_lib2.PDFName.of("Root")), + Encrypt: dict.get(import_pdf_lib2.PDFName.of("Encrypt")), + Info: dict.get(import_pdf_lib2.PDFName.of("Info")), + ID: dict.get(import_pdf_lib2.PDFName.of("ID")), + Prev: dict.get(import_pdf_lib2.PDFName.of("Prev")), + XRefStm: dict.get(import_pdf_lib2.PDFName.of("XRefStm")) + }; + } + } + }; + _PDFParser.prototype.parseTrailerXRefStm = function(offset) { + this.bytes.moveTo(offset); + this.skipWhitespaceAndComments(); + this.parseIndirectObjectHeader(); + this.skipWhitespaceAndComments(); + const object = this.parseObject(); + return import_pdf_lib4.PDFXRefStreamParser.forStream(object).parseEntries(); + }; + _PDFParser.prototype.parseCrossRefSection = function(startOffset) { + return __async(this, null, function* () { + const refEntries = []; + let offset = this.bytes.offset(); + this.bytes.moveTo(startOffset); + this.skipWhitespaceAndComments(); + this.bytes.moveTo(startOffset); + const xrefKeyword = this.matchKeyword(Keywords.xref); + if (!xrefKeyword) { + this.bytes.prev(); + this.skipWhitespaceAndComments(); + offset = this.bytes.offset(); + this.parseIndirectObjectHeader(); + this.skipWhitespaceAndComments(); + const dict = this.parseDict(); + this.bytes.moveTo(offset - Keywords.trailer.length); + const trailer = { + Root: dict.get(import_pdf_lib2.PDFName.of("Root")), + Encrypt: dict.get(import_pdf_lib2.PDFName.of("Encrypt")), + Info: dict.get(import_pdf_lib2.PDFName.of("Info")), + ID: dict.get(import_pdf_lib2.PDFName.of("ID")), + Prev: dict.get(import_pdf_lib2.PDFName.of("Prev")), + XRefStm: dict.get(import_pdf_lib2.PDFName.of("XRefStm")) + }; + if (trailer && Object.keys(this.context.trailerInfo).length === 0) { + this.context.trailerInfo = trailer; + } + const entries = this.parseTrailerXRefStm(offset); + for (const entry of entries) { + if (!refEntries.find((v) => { + if (v.ref.generationNumber === entry.ref.objectNumber) { + return true; + } + })) { + refEntries.push(entry); + } + } + } else if (xrefKeyword) { + offset = this.bytes.offset(); + const trailer = this.parseTrailer(offset); + if (trailer && Object.keys(this.context.trailerInfo).length === 0) { + this.context.trailerInfo = trailer; + } + if (trailer.XRefStm && trailer.XRefStm instanceof import_pdf_lib2.PDFNumber) { + offset = this.bytes.offset(); + const entries2 = this.parseTrailerXRefStm(trailer.XRefStm.asNumber()); + for (const entry of entries2) { + if (!refEntries.find((v) => { + if (v.ref.generationNumber === entry.ref.objectNumber) { + return true; + } + })) { + refEntries.push(entry); + } + } + } + if (trailer == null ? void 0 : trailer.Prev) { + offset = this.bytes.offset(); + const entries2 = yield this.parseCrossRefSection(trailer.Prev.asNumber()); + for (const entry of entries2) { + if (!refEntries.find((v) => { + if (v.ref.generationNumber === entry.ref.objectNumber) { + return true; + } + })) { + refEntries.push(entry); + } + } + this.bytes.moveTo(offset); + } + this.bytes.moveTo(offset); + this.skipWhitespaceAndComments(); + let objectNumber = -1; + const entries = []; + while (!this.bytes.done() && this.bytes.peek() >= 48 && this.bytes.peek() <= 57) { + const firstInt = this.parseRawInt(); + this.skipWhitespaceAndComments(); + const secondInt = this.parseRawInt(); + this.skipWhitespaceAndComments(); + const byte = this.bytes.peek(); + if (byte === import_pdf_lib3.CharCodes.n || byte === import_pdf_lib3.CharCodes.f) { + const ref = import_pdf_lib2.PDFRef.of(objectNumber, secondInt); + const del = this.bytes.next(); + entries.push({ + ref, + inObjectStream: false, + deleted: del === import_pdf_lib3.CharCodes.f ? true : false, + offset: firstInt + }); + objectNumber += 1; + } else { + objectNumber = firstInt; + } + this.skipWhitespaceAndComments(); + } + for (const entry of entries) { + if (!refEntries.find((v) => { + if (v.ref.generationNumber === entry.ref.objectNumber) { + return true; + } + })) { + refEntries.push(entry); + } + } + } else { + throw new Error("Cross-Reference unsupport format."); + } + return refEntries; + }); + }; + _PDFParser.prototype.parseDocument = function(security) { + return __async(this, null, function* () { + if (this.alreadyParsed) { + throw new import_pdf_lib3.ReparseError("PDFParser", "parseDocument"); + } + pdf_lib_Patch._BaseParserPatch(this.bytes); + this.alreadyParsed = true; + this.context.header = this.parseHeader(); + const bodyStartOffset = this.bytes.offset(); + this.bytes.moveEND(); + const refEntries = []; + while (this.bytes.offset() > 0) { + const startxref = this.parseStartxref(this.bytes.offset()); + if (startxref) { + const entries = yield this.parseCrossRefSection(startxref); + for (const entry of entries) { + if (!refEntries.find((v) => { + if (v.ref.generationNumber === entry.ref.objectNumber) { + return true; + } + })) { + refEntries.push(entry); + } + } + } + this.bytes.prev(); + } + if (this.context.trailerInfo.Encrypt) { + if (this.context.trailerInfo.Encrypt instanceof import_pdf_lib2.PDFRef) { + const encryptXref = refEntries.find((v) => { + if (this.context.trailerInfo.Encrypt.objectNumber === v.ref.objectNumber) { + return true; + } + }); + if (!encryptXref) { + throw Error("Encrypt dic not found on CrossReferenceTable"); + } + this.bytes.moveTo(encryptXref.offset); + this.skipWhitespaceAndComments(); + this.parseIndirectObjectHeader(); + this.skipWhitespaceAndComments(); + const edict = this.parseDict(); + const decrypter = PDFSecurity.decrypter(edict, this.context, (security == null ? void 0 : security.password) || "", security == null ? void 0 : security.reqPermissions); + this.context._reEncrypt = decrypter.reEncrypt; + this._decrypter = decrypter.decrypt; + } + } + const encrypt = this.context.trailerInfo.Encrypt; + this.context._encrypt = encrypt; + this.bytes.moveTo(bodyStartOffset); + let prevOffset; + while (!this.bytes.done()) { + yield this.parseDocumentSection(); + const offset = this.bytes.offset(); + if (offset === prevOffset) { + throw new import_pdf_lib3.StalledParserError(this.bytes.position()); + } + prevOffset = offset; + } + this.maybeRecoverRoot(); + if (this.context._encrypt) { + delete this.context.trailerInfo.Encrypt; + } + if (this.context.lookup(import_pdf_lib2.PDFRef.of(0))) { + this.context.delete(import_pdf_lib2.PDFRef.of(0)); + } + return this.context; + }); + }; + _PDFParser.prototype.decryptValue = function(ref, object) { + return __async(this, null, function* () { + const decrypter = this._decrypter; + if (object instanceof import_pdf_lib2.PDFDict) { + const type = object.dict.get(import_pdf_lib2.PDFName.of("Type")); + for (const value of object.dict) { + if (((type == null ? void 0 : type.asString()) === "/Sig" || (type == null ? void 0 : type.asString()) === "/DocTimeStamp") && value[0].asString() === "/Contents") { + continue; + } + if (value[1] instanceof import_pdf_lib2.PDFString) { + const valueBuffer = value[1].asBytes(); + const data = decrypter(valueBuffer, ref.objectNumber, ref.generationNumber); + if (value[0].asString() === "/Cert") { + object.set(import_pdf_lib2.PDFName.of("Cert"), new import_pdf_lib2.PDFHexString(buffer2Hex(data))); + } else { + value[1].value = buffer2Str(data); + } + } else if (value[1] instanceof import_pdf_lib2.PDFHexString) { + const valueBuffer = value[1].asBytes(); + const data = decrypter(valueBuffer, ref.objectNumber, ref.generationNumber); + value[1].value = buffer2Hex(data); + } + if (value[1] instanceof import_pdf_lib2.PDFArray) { + for (const item of value[1].asArray()) { + yield this.decryptValue(ref, item); + } + } + if (value[1] instanceof import_pdf_lib2.PDFDict) { + yield this.decryptValue(ref, value[1]); + } + } + } + if (object instanceof import_pdf_lib2.PDFRawStream) { + const valueBuffer = object.asUint8Array(); + const data = decrypter(valueBuffer, ref.objectNumber, ref.generationNumber); + object.contents = data; + } + if (object instanceof import_pdf_lib2.PDFContentStream) { + const valueBuffer = object.getContents(); + const data = decrypter(valueBuffer, ref.objectNumber, ref.generationNumber); + object.contentsCache.value = data; + } + }); + }; + _PDFParser.prototype.parseIndirectObject = function() { + return __async(this, null, function* () { + var _a; + const ref = this.parseIndirectObjectHeader(); + this.skipWhitespaceAndComments(); + const object = this.parseObject(); + if (this.context._encrypt instanceof import_pdf_lib2.PDFRef && this._decrypter) { + const encryptDicRef = this.context._encrypt; + const type = (_a = object.dict) == null ? void 0 : _a.get(import_pdf_lib2.PDFName.of("Type")); + if ((type == null ? void 0 : type.toString()) !== "/XRef" && encryptDicRef.objectNumber !== ref.objectNumber) { + yield this.decryptValue(ref, object); + } + } + this.skipWhitespaceAndComments(); + this.matchKeyword(Keywords.endobj); + if (object instanceof import_pdf_lib2.PDFRawStream && object.dict.lookup(import_pdf_lib2.PDFName.of("Type")) === import_pdf_lib2.PDFName.of("ObjStm")) { + yield import_pdf_lib4.PDFObjectStreamParser.forStream( + object, + this.shouldWaitForTick + ).parseIntoContext(); + } else if (object instanceof import_pdf_lib2.PDFRawStream && object.dict.lookup(import_pdf_lib2.PDFName.of("Type")) === import_pdf_lib2.PDFName.of("XRef")) { + import_pdf_lib4.PDFXRefStreamParser.forStream(object).parseIntoContext(); + } else { + this.context.assign(ref, object); + } + return ref; + }); + }; + _PDFParser.prototype.jumpNextBody = function() { + this.skipWhitespaceAndComments(); + while (!this.matchKeyword(Keywords.eof) && !this.bytes.done()) { + this.bytes.next(); + } + }; + _PDFParser.prototype.parseDocumentSection = function() { + return __async(this, null, function* () { + yield this.parseIndirectObjects(); + this.jumpNextBody(); + this.skipJibberish(); + }); + }; + _PDFXRefStreamParser.prototype.parseEntries = function() { + const entries = []; + const [typeFieldWidth, offsetFieldWidth, genFieldWidth] = this.byteWidths; + const DecodeParms = this.dict.get(import_pdf_lib2.PDFName.of("DecodeParms")); + if (DecodeParms instanceof import_pdf_lib2.PDFDict) { + const Predictor = DecodeParms.get(import_pdf_lib2.PDFName.of("Predictor")); + const Columns = DecodeParms.get(import_pdf_lib2.PDFName.of("Columns")); + if (Predictor instanceof import_pdf_lib2.PDFNumber && Columns instanceof import_pdf_lib2.PDFNumber) { + const predictorType = Predictor.asNumber(); + const columnNum = Columns.asNumber(); + this.bytes.bytes = predictor(this.bytes.slice(0, this.bytes.length), predictorType, columnNum); + } + } + for (let subsectionIdx = 0, subsectionLen = this.subsections.length; subsectionIdx < subsectionLen; subsectionIdx++) { + const { firstObjectNumber, length } = this.subsections[subsectionIdx]; + for (let objIdx = 0; objIdx < length; objIdx++) { + let type = 0; + for (let idx = 0, len = typeFieldWidth; idx < len; idx++) { + type = type << 8 | this.bytes.next(); + } + let offset = 0; + for (let idx = 0, len = offsetFieldWidth; idx < len; idx++) { + offset = offset << 8 | this.bytes.next(); + } + let generationNumber = 0; + for (let idx = 0, len = genFieldWidth; idx < len; idx++) { + generationNumber = generationNumber << 8 | this.bytes.next(); + } + if (typeFieldWidth === 0) + type = 1; + const objectNumber = firstObjectNumber + objIdx; + const entry = { + ref: import_pdf_lib2.PDFRef.of(objectNumber, generationNumber), + offset, + deleted: type === 0, + inObjectStream: type === 2 + }; + entries.push(entry); + } + } + return entries; + }; + _PDFDocument3.load = function(_0) { + return __async(this, arguments, function* (pdf, options = {}) { + const { + ignoreEncryption = false, + parseSpeed = import_pdf_lib3.ParseSpeeds.Slow, + throwOnInvalidObject = false, + updateMetadata = true, + capNumbers = false + } = options; + (0, import_pdf_lib3.assertIs)(pdf, "pdf", ["string", Uint8Array, ArrayBuffer]); + (0, import_pdf_lib3.assertIs)(ignoreEncryption, "ignoreEncryption", ["boolean"]); + (0, import_pdf_lib3.assertIs)(parseSpeed, "parseSpeed", ["number"]); + (0, import_pdf_lib3.assertIs)(throwOnInvalidObject, "throwOnInvalidObject", ["boolean"]); + const bytes = (0, import_pdf_lib3.toUint8Array)(pdf); + const context = yield import_pdf_lib4.PDFParser.forBytesWithOptions( + bytes, + parseSpeed, + throwOnInvalidObject, + capNumbers + //@ts-ignore + ).parseDocument({ password: options == null ? void 0 : options.password, reqPermissions: options == null ? void 0 : options.reqPermissions }); + const pdfDocument = new PDFDocument(context, ignoreEncryption, updateMetadata); + if (pdfDocument.context._encrypt && !options.unRemoveEncryptDic) { + pdfDocument.context.delete(pdfDocument.context._encrypt); + let maxObjectNumber = 0; + for (const object of pdfDocument.context.enumerateIndirectObjects()) { + maxObjectNumber = Math.max(maxObjectNumber, object[0].objectNumber); + } + pdfDocument.context.largestObjectNumber = maxObjectNumber; + } + return pdfDocument; + }); + }; + } +}; +var predictor = (buffer, type, column) => { + const rows = []; + const rowLength = Math.ceil(buffer.length / (column + 1)); + for (let idx = 0; idx < rowLength; idx++) { + rows.push(buffer.subarray(idx * (column + 1), (idx + 1) * (column + 1))); + } + let length = column; + for (let row = 0; row < rows.length; row++) { + const filterType = rows[row][0]; + if (filterType === 1) { + for (let clm = 2; clm < rows[row].length; clm++) { + if (typeof rows[row][clm] === "number") { + length++; + rows[row][clm] = rows[row][clm] + rows[row][clm - 1]; + } + } + } + if (filterType === 2 && row > 0) { + for (let clm = 1; clm < rows[row].length; clm++) { + if (typeof rows[row][clm] === "number") { + length++; + rows[row][clm] = rows[row][clm] + rows[row - 1][clm]; + } + } + } + if (type === 3) { + for (let clm = 1; clm < rows[row].length; clm++) { + const left = clm > 2 ? rows[row][clm - 1] : 0; + const up = row > 0 ? rows[row - 1][clm] : 0; + if (typeof rows[row][clm] === "number") { + length++; + rows[row][clm] = rows[row][clm] + Math.floor((left + up) / 2); + } + } + } + if (type === 4) { + for (let clm = 1; clm < rows[row].length; clm++) { + const left = clm > 2 ? rows[row][clm - 1] : 0; + const up = row > 0 ? rows[row - 1][clm] : 0; + const upleft = clm > 2 && row > 0 ? rows[row - 1][clm] : 0; + if (typeof rows[row][clm] === "number") { + length++; + rows[row][clm] = paethPredictor(left, up, upleft); + } + } + } + } + const rawData = new Uint8Array(length); + let pos = 0; + let l = 0; + for (const row of rows.map((v) => v.slice(1))) { + rawData.set(row, pos); + pos += column; + l++; + } + return rawData; +}; +var paethPredictor = (left, up, upleft) => { + const p = left + up + upleft; + const pa = Math.abs(p - left); + const pb = Math.abs(p - up); + const pc = Math.abs(p - upleft); + return Math.min(pa, pb, pc); +}; +var copyStringIntoBuffer = (str, buffer, offset, noEncode) => { + const encStr = stringEncode(str, noEncode); + const length = encStr.length; + for (let idx = 0; idx < length; idx++) { + buffer[offset++] = encStr[idx]; + } + return length; +}; +var stringEncode = (str, noEncode) => { + if (noEncode || checkSingleByteCode(str)) { + return new Uint8Array(Array.from(str).map((v) => v.charCodeAt(0))); + } + if (str.charCodeAt(0) === 254 && str.charCodeAt(1) === 255) { + return new Uint8Array(Array.from(str).map((v) => v.charCodeAt(0))); + } + return stringToUTF16(str, "BE", true); +}; +var checkSingleByteCode = (str) => { + for (const c of Array.from(str)) { + if ((c.codePointAt(0) || 256) > 128) { + return false; + } + } + return true; +}; +var stringToUTF16 = (str, byteOrder, BOM) => { + const buffer = new Uint8Array(str.length * 2 + (BOM ? 2 : 0)); + let pos = 0; + if (BOM) { + if (byteOrder === "BE") { + buffer[0] = 254; + buffer[1] = 255; + } else { + buffer[0] = 254; + buffer[1] = 255; + } + pos = 2; + } + for (const char of Array.from(str)) { + const codePoint = char.codePointAt(0); + if (codePoint) { + if (codePoint <= 65535) { + buffer.set(get16to8(codePoint, byteOrder), pos); + pos += 2; + } else if (codePoint <= 1114111) { + const h = ((codePoint - 65536 & 1047552) >> 10) + 55296; + buffer.set(get16to8(h, byteOrder), pos); + pos += 2; + const l = (codePoint & 1023) + 56320; + buffer.set(get16to8(l, byteOrder), pos); + pos += 2; + } + } + } + return buffer; +}; +var get16to8 = (word, order) => { + if (order === "BE") { + return new Uint8Array([(word & 65280) >> 8, word & 255]); + } else { + return new Uint8Array([word & 255, (word & 65280) >> 8]); + } +}; +var { Space, CarriageReturn, Newline } = import_pdf_lib3.CharCodes; +var stream = [ + import_pdf_lib3.CharCodes.s, + import_pdf_lib3.CharCodes.t, + import_pdf_lib3.CharCodes.r, + import_pdf_lib3.CharCodes.e, + import_pdf_lib3.CharCodes.a, + import_pdf_lib3.CharCodes.m +]; +var endstream = [ + import_pdf_lib3.CharCodes.e, + import_pdf_lib3.CharCodes.n, + import_pdf_lib3.CharCodes.d, + import_pdf_lib3.CharCodes.s, + import_pdf_lib3.CharCodes.t, + import_pdf_lib3.CharCodes.r, + import_pdf_lib3.CharCodes.e, + import_pdf_lib3.CharCodes.a, + import_pdf_lib3.CharCodes.m +]; +var Keywords = { + header: [ + import_pdf_lib3.CharCodes.Percent, + import_pdf_lib3.CharCodes.P, + import_pdf_lib3.CharCodes.D, + import_pdf_lib3.CharCodes.F, + import_pdf_lib3.CharCodes.Dash + ], + eof: [ + import_pdf_lib3.CharCodes.Percent, + import_pdf_lib3.CharCodes.Percent, + import_pdf_lib3.CharCodes.E, + import_pdf_lib3.CharCodes.O, + import_pdf_lib3.CharCodes.F + ], + obj: [import_pdf_lib3.CharCodes.o, import_pdf_lib3.CharCodes.b, import_pdf_lib3.CharCodes.j], + endobj: [ + import_pdf_lib3.CharCodes.e, + import_pdf_lib3.CharCodes.n, + import_pdf_lib3.CharCodes.d, + import_pdf_lib3.CharCodes.o, + import_pdf_lib3.CharCodes.b, + import_pdf_lib3.CharCodes.j + ], + xref: [import_pdf_lib3.CharCodes.x, import_pdf_lib3.CharCodes.r, import_pdf_lib3.CharCodes.e, import_pdf_lib3.CharCodes.f], + trailer: [ + import_pdf_lib3.CharCodes.t, + import_pdf_lib3.CharCodes.r, + import_pdf_lib3.CharCodes.a, + import_pdf_lib3.CharCodes.i, + import_pdf_lib3.CharCodes.l, + import_pdf_lib3.CharCodes.e, + import_pdf_lib3.CharCodes.r + ], + startxref: [ + import_pdf_lib3.CharCodes.s, + import_pdf_lib3.CharCodes.t, + import_pdf_lib3.CharCodes.a, + import_pdf_lib3.CharCodes.r, + import_pdf_lib3.CharCodes.t, + import_pdf_lib3.CharCodes.x, + import_pdf_lib3.CharCodes.r, + import_pdf_lib3.CharCodes.e, + import_pdf_lib3.CharCodes.f + ], + true: [import_pdf_lib3.CharCodes.t, import_pdf_lib3.CharCodes.r, import_pdf_lib3.CharCodes.u, import_pdf_lib3.CharCodes.e], + false: [import_pdf_lib3.CharCodes.f, import_pdf_lib3.CharCodes.a, import_pdf_lib3.CharCodes.l, import_pdf_lib3.CharCodes.s, import_pdf_lib3.CharCodes.e], + null: [import_pdf_lib3.CharCodes.n, import_pdf_lib3.CharCodes.u, import_pdf_lib3.CharCodes.l, import_pdf_lib3.CharCodes.l], + stream, + streamEOF1: [...stream, Space, CarriageReturn, Newline], + streamEOF2: [...stream, CarriageReturn, Newline], + streamEOF3: [...stream, CarriageReturn], + streamEOF4: [...stream, Newline], + endstream, + EOF1endstream: [CarriageReturn, Newline, ...endstream], + EOF2endstream: [CarriageReturn, ...endstream], + EOF3endstream: [Newline, ...endstream] +}; +var IsDigit = new Uint8Array(256); +(() => { + pdf_lib_Patch.PDFString_SupportUTF16(import_pdf_lib2.PDFString); + pdf_lib_Patch.SupportEncrypt(import_pdf_lib4.PDFParser, import_pdf_lib5.PDFDocument, import_pdf_lib4.PDFXRefStreamParser); +})(); + +// src/spdf.ts +var decryptPDF = (pdf, ownerPassword) => __async(void 0, null, function* () { + const pdfDoc = yield PDFDocument.load(pdf, { "password": ownerPassword }); + return yield pdfDoc.save({ "useObjectStreams": false }); +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + decryptPDF +}); diff --git a/package.json b/package.json index 6872458..0033957 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,10 @@ "version": "0.1.0", "description": "", "main": "dist/index.js", - "types": "src/index.ts", + "types": "dist/index.d.ts", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "npx tsc --build ." + "build": "tsup src/index.ts --dts" }, "repository": { "type": "git", @@ -20,13 +20,13 @@ "homepage": "https://github.com/RippleRurigaki/sPDF.js#readme", "dependencies": { "@pdf-lib/fontkit": "^1.1.1", - "axios": "^1.3.4", + "@types/crypto-js": "^4.1.1", "crypto-js": "^4.1.1", "jsrsasign": "^10.6.1", "pdf-lib": "^1.17.1", - "saslprep": "^1.0.3", - "typescript": "^5.2.2", - "@types/crypto-js": "^4.1.1", - "@types/saslprep": "^1.0.1" + "typescript": "^5.2.2" + }, + "devDependencies": { + "tsup": "^7.2.0" } } diff --git a/src/PDFSecurity.ts b/src/PDFSecurity.ts index 3a476fb..80dbae2 100644 --- a/src/PDFSecurity.ts +++ b/src/PDFSecurity.ts @@ -21,8 +21,7 @@ is a modifications to use on 'crypto-js' of the calculatePDF20Hash function in Mozilla's pdf.js project, */ -import CryptoJS from 'crypto-js'; -import saslprep from 'saslprep'; +import * as CryptoJS from 'crypto-js'; import {PDFDocument as _PDFDocument,PDFDict,PDFObject,PDFName,PDFNumber,PDFContext,PDFArray,PDFHexString, PDFString, PDFBool} from "pdf-lib"; import { buffer2Hex } from './utils'; @@ -389,13 +388,6 @@ export class PDFSecurity { case 4: this.dictionary = this._setupEncryptionV1V2V4(this.version, options); break; - case 5: - if(this.revesion === 6){ - this.dictionary = this._setupEncryptionV5R6(options) - }else{ - this.dictionary = this._setupEncryptionV5(options); - } - break; } } @@ -481,145 +473,6 @@ export class PDFSecurity { return encDict; } - _setupEncryptionV5(options: SecurityOption): EncDictV5 { - const encDict = { - Filter: 'Standard', - } as EncDictV5; - - this.keyBits = 256; - const permissions = getPermissionsR3(options.permissions); - - const processedUserPassword = processPasswordR5R6(options.userPassword); - const processedOwnerPassword = options.ownerPassword - ? processPasswordR5R6(options.ownerPassword) - : processedUserPassword; - - this.encryptionKey = getEncryptionKeyR5R6( - PDFSecurity.generateRandomWordArray, - ); - const userPasswordEntry = getUserPasswordR5( - processedUserPassword, - PDFSecurity.generateRandomWordArray, - ); - const userKeySalt = CryptoJS.lib.WordArray.create( - userPasswordEntry.words.slice(10, 12), - 8, - ); - const userEncryptionKeyEntry = getUserEncryptionKeyR5( - processedUserPassword, - userKeySalt, - this.encryptionKey, - ); - const ownerPasswordEntry = getOwnerPasswordR5( - processedOwnerPassword, - userPasswordEntry, - PDFSecurity.generateRandomWordArray, - ); - const ownerKeySalt = CryptoJS.lib.WordArray.create( - ownerPasswordEntry.words.slice(10, 12), - 8, - ); - const ownerEncryptionKeyEntry = getOwnerEncryptionKeyR5( - processedOwnerPassword, - ownerKeySalt, - userPasswordEntry, - this.encryptionKey, - ); - const permsEntry = getEncryptedPermissionsR5R6( - permissions, - this.encryptionKey, - PDFSecurity.generateRandomWordArray, - ); - - encDict.V = 5; - encDict.Length = this.keyBits; - encDict.CF = { - StdCF: { - AuthEvent: 'DocOpen', - CFM: 'AESV3', - Length: this.keyBits / 8, - }, - }; - encDict.StmF = 'StdCF'; - encDict.StrF = 'StdCF'; - encDict.R = 5; - encDict.O = PDFHexString.of(buffer2Hex(wordArrayToBuffer(ownerPasswordEntry))); - encDict.OE = PDFHexString.of(buffer2Hex(wordArrayToBuffer(ownerEncryptionKeyEntry))); - encDict.U = PDFHexString.of(buffer2Hex(wordArrayToBuffer(userPasswordEntry))); - encDict.UE = PDFHexString.of(buffer2Hex(wordArrayToBuffer(userEncryptionKeyEntry))); - encDict.P = permissions; - encDict.Perms = PDFHexString.of(buffer2Hex(wordArrayToBuffer(permsEntry))); - return encDict; - } - _setupEncryptionV5R6(options: SecurityOption): EncDictV5 { - const encDict = { - Filter: 'Standard', - } as EncDictV5; - this.keyBits = 256; - const permissions = getPermissionsR3(options.permissions); - - const processedUserPassword = processPasswordR5R6(options.userPassword); - const processedOwnerPassword = options.ownerPassword - ? processPasswordR5R6(options.ownerPassword) - : processedUserPassword; - - this.encryptionKey = getEncryptionKeyR5R6( - PDFSecurity.generateRandomWordArray, - ); - const userPasswordEntry = getUserPasswordR6( - processedUserPassword, - PDFSecurity.generateRandomWordArray, - ); - const userKeySalt = CryptoJS.lib.WordArray.create( - userPasswordEntry.words.slice(10, 12), - 8, - ); - const userEncryptionKeyEntry = getUserEncryptionKeyR6( - processedUserPassword, - userKeySalt, - this.encryptionKey, - ); - const ownerPasswordEntry = getOwnerPasswordR6( - processedOwnerPassword, - userPasswordEntry, - PDFSecurity.generateRandomWordArray, - ); - const ownerKeySalt = CryptoJS.lib.WordArray.create( - ownerPasswordEntry.words.slice(10, 12), - 8, - ); - const ownerEncryptionKeyEntry = getOwnerEncryptionKeyR6( - processedOwnerPassword, - ownerKeySalt, - userPasswordEntry, - this.encryptionKey, - ); - const permsEntry = getEncryptedPermissionsR5R6( - permissions, - this.encryptionKey, - PDFSecurity.generateRandomWordArray, - ); - encDict.V = 5; - encDict.Length = this.keyBits; - encDict.CF = { - StdCF: { - AuthEvent: 'DocOpen', - CFM: 'AESV3', - Length: this.keyBits / 8, - }, - }; - encDict.StmF = 'StdCF'; - encDict.StrF = 'StdCF'; - encDict.R = 6; - encDict.O = PDFHexString.of(buffer2Hex(wordArrayToBuffer(ownerPasswordEntry))); - encDict.OE = PDFHexString.of(buffer2Hex(wordArrayToBuffer(ownerEncryptionKeyEntry))); - encDict.U = PDFHexString.of(buffer2Hex(wordArrayToBuffer(userPasswordEntry))); - encDict.UE = PDFHexString.of(buffer2Hex(wordArrayToBuffer(userEncryptionKeyEntry))); - encDict.P = permissions; - encDict.Perms = PDFHexString.of(buffer2Hex(wordArrayToBuffer(permsEntry))); - return encDict; - } - getEncryptFn(obj: number, gen: number) { return _getEncryptFn(obj,gen,this.version,this.keyBits,this.encryptionKey); } @@ -795,147 +648,6 @@ const getEncryptionKeyR2R3R4 = ( } return key; }; - -const getUserPasswordR5 = ( - processedUserPassword: WordArray, - generateRandomWordArray: generateRandomWordArrayFn, -) => { - const validationSalt = generateRandomWordArray(8); - const keySalt = generateRandomWordArray(8); - return CryptoJS.SHA256(processedUserPassword.clone().concat(validationSalt)) - .concat(validationSalt) - .concat(keySalt); -}; -const getUserPasswordR6= ( - processedUserPassword: WordArray, - generateRandomWordArray: generateRandomWordArrayFn, -) => { - const validationSalt = generateRandomWordArray(8); - const keySalt = generateRandomWordArray(8); - return getPDFSecurityHashR6( - processedUserPassword - ,processedUserPassword.clone().concat(validationSalt) - ,CryptoJS.lib.WordArray.create()) - .concat(validationSalt) - .concat(keySalt); -}; -const getUserEncryptionKeyR5 = ( - processedUserPassword: WordArray, - userKeySalt: WordArray, - encryptionKey: WordArray, -) => { - const key = CryptoJS.SHA256( - processedUserPassword.clone().concat(userKeySalt), - ); - const options = { - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.NoPadding, - iv: CryptoJS.lib.WordArray.create((null as unknown) as undefined, 16), - }; - return CryptoJS.AES.encrypt(encryptionKey, key, options).ciphertext; -}; -const getUserEncryptionKeyR6= ( - processedUserPassword: WordArray, - userKeySalt: WordArray, - encryptionKey: WordArray, -) => { - const key = getPDFSecurityHashR6( - processedUserPassword - ,processedUserPassword.clone().concat(userKeySalt) - ,CryptoJS.lib.WordArray.create()); - const options = { - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.NoPadding, - iv: CryptoJS.lib.WordArray.create((null as unknown) as undefined, 16), - }; - return CryptoJS.AES.encrypt(encryptionKey, key, options).ciphertext; -}; -const getOwnerPasswordR5 = ( - processedOwnerPassword: WordArray, - userPasswordEntry: WordArray, - generateRandomWordArray: generateRandomWordArrayFn, -) => { - const validationSalt = generateRandomWordArray(8); - const keySalt = generateRandomWordArray(8); - return CryptoJS.SHA256( - processedOwnerPassword - .clone() - .concat(validationSalt) - .concat(userPasswordEntry), - ) - .concat(validationSalt) - .concat(keySalt); -}; -const getOwnerPasswordR6 = ( - processedOwnerPassword: WordArray, - userPasswordEntry: WordArray, - generateRandomWordArray: generateRandomWordArrayFn, -) => { - const validationSalt = generateRandomWordArray(8); - const keySalt = generateRandomWordArray(8); - return getPDFSecurityHashR6( - processedOwnerPassword - ,processedOwnerPassword.clone().concat(validationSalt).concat(userPasswordEntry) - ,userPasswordEntry) - .concat(validationSalt) - .concat(keySalt); -}; -const getOwnerEncryptionKeyR5 = ( - processedOwnerPassword: WordArray, - ownerKeySalt: WordArray, - userPasswordEntry: WordArray, - encryptionKey: WordArray, -) => { - const key = CryptoJS.SHA256( - processedOwnerPassword - .clone() - .concat(ownerKeySalt) - .concat(userPasswordEntry), - ); - const options = { - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.NoPadding, - iv: CryptoJS.lib.WordArray.create((null as unknown) as undefined, 16), - }; - return CryptoJS.AES.encrypt(encryptionKey, key, options).ciphertext; -}; -const getOwnerEncryptionKeyR6 = ( - processedOwnerPassword: WordArray, - ownerKeySalt: WordArray, - userPasswordEntry: WordArray, - encryptionKey: WordArray, -) => { - const key = getPDFSecurityHashR6( - processedOwnerPassword - ,processedOwnerPassword.clone().concat(ownerKeySalt).concat(userPasswordEntry) - ,userPasswordEntry); - const options = { - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.NoPadding, - iv: CryptoJS.lib.WordArray.create((null as unknown) as undefined, 16), - }; - return CryptoJS.AES.encrypt(encryptionKey, key, options).ciphertext; -}; -const getEncryptionKeyR5R6 = ( - generateRandomWordArray: generateRandomWordArrayFn, -) => generateRandomWordArray(32); - -const getEncryptedPermissionsR5R6 = ( - permissions: number, - encryptionKey: WordArray, - generateRandomWordArray: generateRandomWordArrayFn, -) => { - const cipher = CryptoJS.lib.WordArray.create( - [lsbFirstWord(permissions), 0xffffffff, 0x54616462], - 12, - ).concat(generateRandomWordArray(4)); - const options = { - mode: CryptoJS.mode.ECB, - padding: CryptoJS.pad.NoPadding, - }; - return CryptoJS.AES.encrypt(cipher, encryptionKey, options).ciphertext; -}; - const processPasswordR2R3R4 = (password = '') => { const out = new Uint8Array(32); const length = password.length; @@ -955,20 +667,6 @@ const processPasswordR2R3R4 = (password = '') => { return CryptoJS.lib.WordArray.create((out as unknown) as number[]); }; -const processPasswordR5R6 = (password = '') => { - password = decodeURI(encodeURIComponent(saslprep(password))); - const length = Math.min(127, password.length); - const out = new Uint8Array(length); - - for (let i = 0; i < length; i++) { - out[i] = password.charCodeAt(i); - } - - return CryptoJS.lib.WordArray.create((out as unknown) as number[]); -}; - - - const lsbFirstWord = (data: number): number => ((data & 0xff) << 24) | ((data & 0xff00) << 8) | @@ -1020,52 +718,7 @@ const checkUserpassword = (pram:{ return; } }else if(pram.version === 5){ - if((pram.securityRevision === 5 || pram.securityRevision === 6) && pram.UE && pram.Perms){ - const UValid = CryptoJS.lib.WordArray.create(pram.U.subarray(0,32) as unknown as number[]); - const UEWord = CryptoJS.lib.WordArray.create(pram.UE as unknown as number[]); - const PermsWord = CryptoJS.lib.WordArray.create(pram.Perms as unknown as number[]); - const userValidationSalt = CryptoJS.lib.WordArray.create(pram.U.subarray(32,32+8) as unknown as number[]); - const userKeySalt = CryptoJS.lib.WordArray.create(pram.U.subarray(32+8,32+8+8) as unknown as number[]); - const processedPassword = processPasswordR5R6(pram.userPassword); - const saltingValidPassword = processedPassword.clone().concat(userValidationSalt); - const validhash = pram.securityRevision === 5 - ? CryptoJS.SHA256(saltingValidPassword) - :getPDFSecurityHashR6( - processedPassword - ,processedPassword.clone().concat(userValidationSalt) - ,CryptoJS.lib.WordArray.create()); - if(validhash.toString() !== UValid.toString()){ - // passwotd is not userpassword - return false; - } - const intermediateUserKey = pram.securityRevision === 5 - ?CryptoJS.SHA256(processedPassword.clone().concat(userKeySalt)) - :getPDFSecurityHashR6( - processedPassword - ,processedPassword.clone().concat(userKeySalt) - ,CryptoJS.lib.WordArray.create()); - const fileEncryptionKey = CryptoJS.AES.decrypt( - CryptoJS.lib.CipherParams.create({ciphertext:UEWord}) - ,intermediateUserKey - ,{"iv":CryptoJS.lib.WordArray.create((null as unknown) as undefined, 16),padding: CryptoJS.pad.NoPadding,mode:CryptoJS.mode.CBC} - ); - const decPerms = wordArrayToBuffer(CryptoJS.AES.decrypt( - CryptoJS.lib.CipherParams.create({ciphertext:PermsWord}) - ,fileEncryptionKey - ,{"iv":CryptoJS.lib.WordArray.create((null as unknown) as undefined, 16),padding: CryptoJS.pad.NoPadding,mode:CryptoJS.mode.ECB}) - ); - const adb = Array.from("adb").map(v=>v.charCodeAt(0)); - if(decPerms[9] !== adb[0] || decPerms[10] !== adb[1] || decPerms[11] !== adb[2]){ - //"Perms decrypt error" - return false; - } - const permission = (decPerms[3] << 24) + (decPerms[2] << 16) + (decPerms[1] << 8) + decPerms[0]; - if(permission !== pram.P){ - //"Perms decrypt error" - return false; - } - return fileEncryptionKey; - } + return } } const userPasswordAuthV4 = (pram:{ @@ -1131,53 +784,7 @@ const checkOwnerpassword = (pram:{ return; } }else if(pram.version === 5){ - if((pram.securityRevision===5 || pram.securityRevision === 6) &&pram.OE){ - const Uword = CryptoJS.lib.WordArray.create(pram.U as unknown as number[]); - const OEWord = CryptoJS.lib.WordArray.create(pram.OE as unknown as number[]); - const validO = CryptoJS.lib.WordArray.create(pram.O.subarray(0,32) as unknown as number[]); - const PermsWord = CryptoJS.lib.WordArray.create(pram.Perms as unknown as number[]); - const ownerValidationSalt = CryptoJS.lib.WordArray.create(pram.O.subarray(32,32+8) as unknown as number[]); - const ownerKeySalt = CryptoJS.lib.WordArray.create(pram.O.subarray(32+8,32+8+8) as unknown as number[]); - const processedPassword = processPasswordR5R6(pram.ownerPassword); - const validHash = pram.securityRevision === 5 - ?CryptoJS.SHA256(processedPassword.clone().concat(ownerValidationSalt).concat(Uword)) - :getPDFSecurityHashR6( - processedPassword - ,processedPassword.clone().concat(ownerValidationSalt).concat(Uword) - ,Uword); - if(validHash.toString() !== validO.toString()){ - //not ownerpassword; - return false; - } - const intermediateOwnerKey = pram.securityRevision === 5 - ?CryptoJS.SHA256(processedPassword.clone().concat(ownerKeySalt).concat(Uword)) - :getPDFSecurityHashR6( - processedPassword - ,processedPassword.clone().concat(ownerKeySalt).concat(Uword) - ,Uword); - const fileEncryptionKey = CryptoJS.AES.decrypt( - CryptoJS.lib.CipherParams.create({ciphertext:OEWord}) - ,intermediateOwnerKey - ,{"iv":CryptoJS.lib.WordArray.create((null as unknown) as undefined, 16),padding: CryptoJS.pad.NoPadding,mode:CryptoJS.mode.CBC} - ); - const decPerms = wordArrayToBuffer(CryptoJS.AES.decrypt( - CryptoJS.lib.CipherParams.create({ciphertext:PermsWord}) - ,fileEncryptionKey - ,{"iv":CryptoJS.lib.WordArray.create((null as unknown) as undefined, 16),padding: CryptoJS.pad.NoPadding,mode:CryptoJS.mode.ECB}) - ); - const adb = Array.from("adb").map(v=>v.charCodeAt(0)); - if(decPerms[9] !== adb[0] || decPerms[10] !== adb[1] || decPerms[11] !== adb[2]){ - //Perms decrypt error - return false; - } - const permission = (decPerms[3] << 24) + (decPerms[2] << 16) + (decPerms[1] << 8) + decPerms[0]; - if(permission !== pram.P){ - //Perms decrypt error - return false; - } - //throw 0; - return fileEncryptionKey; - } + return } } const getDecryptFn = (version:number,encryptionKey:WordArray,keyBits:number)=>{ @@ -1290,61 +897,6 @@ const _getEncryptFn = (obj: number, gen: number,version:number,keyBits:number,en ), ); } - -const getPDFSecurityHashR6 = ( - processedPassword : WordArray, - salt:WordArray, - U:WordArray, -)=>{ - let hash = CryptoJS.SHA256(salt); - let intermediateKey = CryptoJS.lib.WordArray.create(); - - let idx = 0; - while(idx < 64 || wordArrayToBuffer(intermediateKey)[intermediateKey.sigBytes-1] > idx - 32){ - const comb = processedPassword.clone().concat(hash).concat(U); - const intermediateKey2 = CryptoJS.lib.WordArray.create(); - for(let idy=0;idy<64;idy++){ - intermediateKey2.concat(comb) - } - intermediateKey = CryptoJS.AES.encrypt( - intermediateKey2, - CryptoJS.lib.WordArray.create(hash.words.slice(0,4)), - {iv:CryptoJS.lib.WordArray.create(hash.words.slice(4,8)),padding: CryptoJS.pad.NoPadding,mode:CryptoJS.mode.CBC} - ).ciphertext; - const r16 = intermediateKey.clone(); - r16.sigBytes = 16; - r16.clamp(); - // r16 % 3 = ??? - // !! Unable 128bit modulo on JavaScript. - // Equivalence: - // :(A+B) % 3 = ((A % 3) + (B % 3)) % 3 - // :(A*B) % 3 = ((A % 3) * (B % 3)) % 3 - // - // (2**8) % 3 = 1 , (2**8)*(2**8) % 3 = ((2**8) % 3 * (2**8) %3 ) % 3 = (1*1) % 3 = 1 % 3 = 1 - // :(2**(8*n)) % 3 = 1 - // :(A * 2**(8*n)) % 3 = (A % 3 * 1 % 3) = (A %3 * 1) % 3 = (A % 3) % 3 = A % 3 - // r16 % 3 = ((r16[0] * 2**(8*15)) % 3 + (r16[1] * 2**(8*14)) %3 + (r16[2] * 2**(8*13)) % 3 + ... + (r16[15] *2**(8*0))) % 3 - // = ((r16[0] % 3) * (2**(8*15)) % 3) % 3) % 3 + ... - // = ((r16[0] % 3) * 1 % 3) % 3 + ... - // = ((r16[0] % 3) % 3) % 3 + ... - // = r16[0] % 3 + r16[1] % 3 + r16[2] % 3 + ... + r16[15] % 3 - // = (r16[0] + r16[1] + r16[2] + ... + r16[15]) % 3 - // 255*16 < Number.MAX_SAFE_INTEGER. - // OK, That is, every byte is added, to get modulo 3. - const remainder = (wordArrayToBuffer(r16).reduce((a,b)=>a+b,0)) % 3; - if(remainder === 0){ - hash = CryptoJS.SHA256(intermediateKey); - }else if(remainder === 1){ - hash = CryptoJS.SHA384(intermediateKey); - }else{ - hash = CryptoJS.SHA512(intermediateKey); - } - idx++; - } - hash.sigBytes = 32; - hash.clamp(); - return hash; -} /* 7.6.3.3 Encryption Key Algorithm Algorithm 2 diff --git a/src/pdf-lib_patch.ts b/src/pdf-lib_patch.ts index 49a06d3..6b601c2 100644 --- a/src/pdf-lib_patch.ts +++ b/src/pdf-lib_patch.ts @@ -5,20 +5,15 @@ Licensed under the MIT license. */ import {PDFDict, PDFNumber, PDFArray, PDFRawStream, PDFString, PDFHexString, PDFObject,PDFName,PDFRef,PDFContentStream} from "pdf-lib"; -import {CharCodes,assertIs,ParseSpeeds,toUint8Array, escapeRegExp,ReparseError,StalledParserError} from "pdf-lib"; +import {CharCodes,assertIs,ParseSpeeds,toUint8Array,ReparseError,StalledParserError} from "pdf-lib"; import {PDFXRefStreamParser,PDFParser,PDFObjectStreamParser} from "pdf-lib"; -import {PDFSecurity,UserPermission as _UserPermission,SecurityOption} from "./PDFSecurity"; +import {PDFSecurity,UserPermission as _UserPermission} from "./PDFSecurity"; import {buffer2Hex, buffer2Str} from "./utils"; import {PDFDocument as _PDFDocument, LoadOptions as _LoadOptions, PDFContext as _PDFContext} from "pdf-lib"; export interface PDFDocument extends _PDFDocument { load:(pdf: string | Uint8Array | ArrayBuffer, options?: LoadOptions)=> Promise; create:()=> Promise; - encrypt:(pram:{ - userPassword:string, - ownerPassword:string, - keyBits:128|256, - permission:UserPermission,})=>Promise, context:PDFContext, } interface PDFContext extends _PDFContext{ @@ -315,7 +310,6 @@ const pdf_lib_Patch = { } if (this.context.lookup(PDFRef.of(0))) { - console.warn('Removing parsed object: 0 0 R'); this.context.delete(PDFRef.of(0)); } @@ -526,89 +520,6 @@ const pdf_lib_Patch = { } return pdfDocument; } - _PDFDocument.prototype.encrypt = async function (pram:{ - userPassword:string, - ownerPassword:string, - keyBits:128|256, - permission:UserPermission,} - ) { - //ADD:Support encrypt objects. - const options:SecurityOption = { - "userPassword":pram.userPassword, - "ownerPassword":pram.ownerPassword, - "permissions":pram.permission, - "pdfVersion":pram.keyBits===256?"2.0":"1.7", - } - if(!this.context.trailerInfo.ID){ - const docID = PDFHexString.of(buffer2Hex(PDFSecurity.generateFileID(this.getInfoDict()))); - const idArray = PDFArray.withContext(this.context); - idArray.push(docID); - idArray.push(docID); - this.context.trailerInfo.ID = idArray; - } - const security = PDFSecurity.create(this, options); - const newSecurity = this.context.obj(security.dictionary); - this.context.trailerInfo.Encrypt = this.context.register(newSecurity); - const encryptDicObjectNumber = this.context.trailerInfo.Encrypt.objectNumber; - await this.flush(); - for (const obj of this.context.enumerateIndirectObjects()){ - const ref = obj[0]; - if(ref.objectNumber !== encryptDicObjectNumber){ - encryptValue(obj[0],obj[1],security) - } - } - } - } -} -const encryptValue = (ref:PDFRef,object:PDFObject,security:PDFSecurity) =>{ - if(object instanceof PDFDict){ - //@ts-ignore - const type = object.dict.get(PDFName.of("Type")) as PDFName; - //@ts-ignore - for(const value of object.dict){ - if(type?.asString() === "/Sig" && value[0].asString() === "/Contents"){ - //Skip SignContents - continue; - } - const encrypter = security.getEncryptFn(ref.objectNumber,ref.generationNumber); - if(value[1] instanceof PDFString){ - const valueBuffer = new Uint8Array(value[1].sizeInBytes()); - value[1].copyBytesInto(valueBuffer,0); - const data = encrypter(valueBuffer.subarray(1,valueBuffer.length-1)) as Uint8Array - //@ts-ignore , - value[1].value = escapeRegExp(buffer2Str(data)); - //@ts-ignore - value[1]._noEncode = true; - } - if(value[1] instanceof PDFHexString){ - const valueBuffer = value[1].asBytes(); - const data = encrypter(valueBuffer) - //@ts-ignore , - value[1].value = buffer2Hex(data); - } - if(value[1] instanceof PDFArray){ - for(const item of value[1].asArray()){ - encryptValue(ref,item,security) - } - } - if(value[1] instanceof PDFDict){ - encryptValue(ref,value[1],security); - } - } - } - if(object instanceof PDFRawStream){ - const encrypter = security.getEncryptFn(ref.objectNumber,ref.generationNumber); - const valueBuffer = object.asUint8Array(); - const data = encrypter(valueBuffer) - //@ts-ignore , - object.contents = data; - } - if(object instanceof PDFContentStream){ - const encrypter = security.getEncryptFn(ref.objectNumber,ref.generationNumber); - const valueBuffer = object.getContents(); - const data = encrypter(valueBuffer) - //@ts-ignore , - object.contentsCache.value = data; } } const predictor = (buffer:Uint8Array,type:number,column:number) => { diff --git a/src/signTool.ts b/src/signTool.ts deleted file mode 100644 index 0c199ed..0000000 --- a/src/signTool.ts +++ /dev/null @@ -1,758 +0,0 @@ -import {KJUR,X509,KEYUTIL,ASN1HEX, X509CRL,zulutodate,pemtohex} from "jsrsasign"; -import axios, { AxiosError } from 'axios'; -import {buffer2Hex,buffer2Str,hex2buffer,Log} from "./utils"; - -type SupportHashAlgorithm = JSRSASIGN_SupportHashAlg & ('sha1'|'sha256'|'sha384'|'sha512') -const defaultHashAlgoritm = 'sha256'; -export interface DSSTable{ - certs:Array, - ocsps:Array, - crls:Array, -} -interface CertId{sn:string,issuer:string} -export interface IgetSignedHexOptions{ - hashalg?:SupportHashAlgorithm, - tsa?:{URL:string,hashalg?:SupportHashAlgorithm,}, -} -class CertChain{ - private certs:Array; - private invalidCerts?:Array<{pem:string,subjectString:string}>; - private allCains:boolean; - private ignoreMissingTrustChain?:boolean; - private ignoreRevokedCert?:boolean; - - constructor(certs:Array,options:{ignoreMissingTrustChain?:boolean,ignoreRevokedCert?:boolean}){ - this.certs = certs; - this.allCains = false; - this.ignoreMissingTrustChain = options.ignoreMissingTrustChain; - this.ignoreRevokedCert = options.ignoreRevokedCert; - } - public getChains = async ()=> { - this.certs.push(...(await this._getCAIssertCrt())); - this._deduplicationCert(); - this.invalidCerts = this._checkCertChain().map(v=>{return {pem:certHex2PEM(v.hex),subjectString:v.getSubjectString()}}); - if(this.invalidCerts.length === 0){ - this.allCains = true; - } - return this.ignoreMissingTrustChain||this.allCains; - } - - public getCerts = ()=>{ - if(this.ignoreMissingTrustChain||this.allCains){ - return this.certs; - } - return; - } - public getInvalidCerts = ()=>this.invalidCerts; - - public getIssuertCert = (cert:X509|string) => { - return (()=>{ - for(const _cert of this.certs){ - const certObj = new X509(buffer2Hex(_cert)); - if(cert instanceof X509){ - if(certObj.getSubjectHex() ===cert.getIssuerHex()){ - const publicKey = certObj.getPublicKey(); - if(cert.verifySignature(publicKey)){ - return certObj; - } - } - }else if(typeof cert === "string"){ - if(cert.match(/^\//)){ - if(certObj.getSubjectString() === cert){ - return certObj; - } - } - } - } - })(); - } - - public checkCRL = (crls:Array,signInfos?:Array<{signDate:Date,signerCert:Uint8Array}>) => { - SignTool.LOG.debug(`CheckCRL`); - SignTool.LOG.debug(`Include ${crls.length} CRLs`) - const foundCRL:Array = []; - for(const _cert of this.certs){ - const cert = new X509(buffer2Hex(_cert)); - const pram = { - issuer:cert.getIssuerHex(), - sn:cert.getSerialNumberHex(), - subject:cert.getSubjectHex(), - } - SignTool.LOG.debug(cert.getSubjectString()); - if(pram.issuer === pram.subject){ - //self sing, maybe root CA. - SignTool.LOG.debug(" Self sign") - foundCRL.push(true); - }else{ - const crl = crls.filter(v=>{ - const _X509 = new X509CRL(buffer2Hex(v)); - if(_X509.getIssuerHex() === pram.issuer){ - SignTool.LOG.debug(" CRL Found."); - const _issuer = this.getIssuertCert(cert); - if(!_issuer){ - SignTool.LOG.debug(" CRL Issuer not found."); - return false; - } - if(!_X509.verifySignature(_issuer.getPublicKey())){ - SignTool.LOG.debug(" CRL Issuer invalid."); - return false; - } - SignTool.LOG.debug(" CRL Issuer valid."); - return true; - } - }); - if(crl.length>0){ - let revokeInCrl = false; - for(const _crl of crl){ - //Revoke check - const crlObj = new X509CRL(buffer2Hex(_crl)); - const revoke = crlObj.findRevCertBySN(cert.getSerialNumberHex()); - if(revoke){ - SignTool.LOG.debug(" !revoked!") - const revokeDate = zulutodate(revoke.date); - if(!signInfos){ - revokeInCrl = true; - }else{ - const signer = signInfos.find(v=>{ - const sicert = new X509(buffer2Hex(v.signerCert)); - if(cert.getSubjectHex() === sicert.getSubjectHex() && cert.getSerialNumberHex() === sicert.getSerialNumberHex()){ - return true; - } - }); - SignTool.LOG.debug(`Singed date:${signer?.signDate.toString()}`) - if(signer && revokeDate.getTime() < signer.signDate.getTime()){ - revokeInCrl = true; - SignTool.LOG.debug(` Revoked at ${revokeDate.toString()}`); - continue; - } - } - } - } - if(revokeInCrl){ - foundCRL.push(false); - }else{ - foundCRL.push(true); - } - }else{ - SignTool.LOG.debug(" CRL not found."); - foundCRL.push(false); - } - } - } - return foundCRL; - } - public checkOCSP = (ocsps:Array) => { - SignTool.LOG.debug(`CheckOCSP`); - SignTool.LOG.debug(`Include ${ocsps.length} OCSPs`) - const foundOCSP:Array = []; - for(const _cert of this.certs){ - const cert = new X509(buffer2Hex(_cert)); - const pram = { - issuer:cert.getIssuerHex(), - sn:cert.getSerialNumberHex(), - subject:cert.getSubjectHex(), - } - SignTool.LOG.debug(cert.getSubjectString()); - if(pram.issuer === pram.subject){ - //self sing, maybe root CA. - SignTool.LOG.debug(" Self sign") - foundOCSP.push(true); - }else{ - const ocsp = ocsps.filter(v=>{ - try{ - const ocspPaser = new KJUR.asn1.ocsp.OCSPParser(); - const ocspObj = ocspPaser.getOCSPResponse(buffer2Hex(v)); - const issuer = this.getIssuertCert(ocspObj.respid.name.str); - if(!issuer){ - return false; - } - const responseData = new KJUR.asn1.ocsp.ResponseData(ocspObj); - const signHex = responseData.tohex(); - const sig = new KJUR.crypto.Signature({"alg": ocspObj.alg}); - sig.init(issuer.getPublicKey()); - sig.updateHex(signHex); - if(sig.verify(ocspObj.sighex)){ - for(const ocspCert of ocspObj.array){ - const isname = SignTool.getHash(hex2buffer(pram.issuer),ocspCert.certid.alg); - if(isname === ocspCert.certid.issname && pram.sn === ocspCert.certid.sbjsn){ - SignTool.LOG.debug(` Found OCSP response.`) - SignTool.LOG.debug(` OCSP Status:${ocspCert.status.status}`) - if(ocspCert.status.status==="good"){ - return true; - } - } - } - } - return false; - }catch(e){ - return false; - } - }); - if(ocsp.length>0){ - foundOCSP.push(true); - }else{ - foundOCSP.push(false); - } - } - } - return foundOCSP; - } - - private _deduplicationCert = () => { - const _work:Array = []; - for(const crt of this.certs){ - const cert = new X509(buffer2Hex(crt)); - if(!_work.find(v=>{ - const _x509 = new X509(buffer2Hex(v)); - if(_x509.getIssuerString() === cert.getIssuerString() && _x509.getSerialNumberHex() === cert.getSerialNumberHex()){ - return true; - } - })){ - _work.push(crt) - } - } - this.certs = _work; - } - - private _getCAIssertCrt = async (subCerts?:Uint8Array):Promise> => { - try{ - const certs:Array = []; - for(const certData of subCerts?[subCerts]:this.certs){ - const cert = new X509(buffer2Hex(certData)); - const _issuer = this.getIssuertCert(cert); - if(_issuer){ - continue; - } - const AIAInfo = cert.getExtAIAInfo(); - if(AIAInfo?.caissuer){ - for(const caissuerUrl of AIAInfo.caissuer){ - if(caissuerUrl){ - SignTool.LOG.debug(`Get CA Cert:${caissuerUrl}`) - const caissuerCert = await getBufferFromUrl(caissuerUrl); - const issuerX509 = (()=>{ - try{ - const txtDec = new TextDecoder(); - const _certStr = txtDec.decode(caissuerCert); - if(_certStr.includes("-BEGIN CERTIFICATE-")){ - const _x509 = new X509(_certStr); - return hex2buffer(_x509.hex); - }else{ - const _x509 = new X509(certHex2PEM(buffer2Hex(caissuerCert))); - return hex2buffer(_x509.hex); - } - }catch(e){ - throw new Error(`${caissuerUrl} is unsupport format`); - } - })(); - if(!issuerX509){ - throw new Error(`${caissuerUrl} is unsupport format`); - } - certs.push(issuerX509); - const _issuerX509 = new X509(buffer2Hex(issuerX509)); - if(_issuerX509.getSubjectHex() !== _issuerX509.getIssuerHex()){ - const issuerIssuer = await this._getCAIssertCrt(issuerX509); - certs.push(...issuerIssuer); - } - } - } - } - } - return certs; - }catch(e){ - throw new Error('CaIssuers Get failed'); - } - } - public _checkCertChain = () => { - const _certs:{[id:string]:{x509:X509,hasIssuercert:boolean}} = {}; - SignTool.LOG.debug(`${this.certs.length} Certs chain check`) - const certs = this.certs.map(v=>new X509(buffer2Hex(v))); - for(const x509 of certs){ - const _id = x509.getIssuerHex()+x509.getSerialNumberHex(); - _certs[_id] = {x509:x509,hasIssuercert:false}; - } - for(const [id,cert] of Object.entries(_certs)){ - SignTool.LOG.debug(`Subject=${cert.x509.getSubjectString()},Issuer=${cert.x509.getIssuerString()}`) - if(cert.x509.getSubjectHex() === cert.x509.getIssuerHex()){ - const publicKey = cert.x509.getPublicKey(); - if(cert.x509.verifySignature(publicKey)){ - SignTool.LOG.debug(` :Self sign.`) - cert.hasIssuercert = true; - } - }else{ - const issuer = certs.filter(v=>{ - if(cert.x509.getIssuerHex() === v.getSubjectHex()) return true; - }); - if(issuer.length===0){ - SignTool.LOG.debug(` :Issuer cert not found.`) - if(!this.ignoreMissingTrustChain){ - throw new Error("Isuuer cert not found\r\n"+cert.x509.getSubjectString()); - } - }else{ - for(const _issuer of issuer){ - const publicKey = _issuer.getPublicKey(); - if(cert.x509.verifySignature(publicKey)){ - SignTool.LOG.debug(` :Issuer cert found.`) - cert.hasIssuercert = true; - break; - } - } - } - } - } - const invalidCerts:Array = [] - for(const [id,cert] of Object.entries(_certs)){ - if(!cert.hasIssuercert){ - invalidCerts.push(cert.x509) - } - } - return invalidCerts; - } -} -class DSS{ - private signInfo:Array<{signDate:Date,signerCert:Uint8Array}>; - private crls:Array; - private certs:Array; - private cChain?:CertChain; - - constructor(){ - this.signInfo = []; - this.crls = []; - this.certs = []; - } - public fetchSignerCerts = (signedCMS:Array) => { - this.signInfo = []; - signedCMS.forEach(v=>this._fetchSignerCert(v)); - } - - private _fetchSignerCert = (signedDer:Uint8Array) => { - SignTool.LOG.debug("fetchSignerCert"); - try{ - const cmsParser = new KJUR.asn1.cms.CMSParser(); - const tspParser = new KJUR.asn1.tsp.TSPParser(); - const cmsData = cmsParser.getCMSSignedData(buffer2Hex(signedDer)); - const certs:Array = []; - certs.push(...(cmsData.certs?.array||[]).map(v=>new X509(buffer2Hex(SignTool.getCert(v))))); - for(const sinfo of cmsData.sinfos){ - if(sinfo.id.type === "isssn"){ - const signerCertObj = certs.find(v=>{ - if(v.getIssuerString()===sinfo.id.issuer.str && v.getSerialNumberHex() === sinfo.id.serial.hex){ - return true; - } - }); - if(signerCertObj){ - const signedDate = (()=>{ - if(cmsData.sinfos[0].sattrs?.array){ - for(const attr of cmsData.sinfos[0].sattrs?.array){ - if(attr.attr === 'signingTime' && attr.str){ - return zulutodate(attr.str); - } - } - } - return new Date(); - })(); - SignTool.LOG.debug(` singned Date:${signedDate.toString()}`); - SignTool.LOG.debug(` singned By:${signerCertObj.getSubjectString()}`); - this.signInfo.push({ - signDate:signedDate, - signerCert:hex2buffer(signerCertObj.hex), - }); - if(sinfo?.uattrs && Array.isArray(sinfo?.uattrs?.array)){ - //TimeStamp - const tTokens = sinfo.uattrs.array.filter(v=>{ - if(v.attr==="timeStampToken"){ - return true; - } - }); - for(const _tToken of tTokens){ - if(_tToken.valhex){ - const tspData = tspParser.getToken(_tToken.valhex); - if(tspData.certs?.array){ - SignTool.LOG.debug(` Timestanp Token found.`); - this.certs.push(...tspData.certs?.array.map(v=>SignTool.getCert(v))); - } - } - } - } - break; - }else{ - throw new Error("Signer cert not found.*") - } - } - } - }catch(e){ - throw new Error('Fetch signercert failed'); - } - } - public importCRLs = (crls:Array) => { - this.crls.push(...crls.map(v=>SignTool.getCrl(v))); - } - public importCerts = (certs:Array) => { - this.certs.push(...certs.map(v=>SignTool.getCert(v))); - } - public getDSSTable = async (pram:{ignoreMissingTrustChain:boolean,ignoreRevokedCert:boolean}) => { - const retdss:DSSTable = { - certs:[], - ocsps:[], - crls:[], - } - const certs:Array = []; - const checkCerts = []; - checkCerts.push(...this.signInfo.map(v=>v.signerCert)); - checkCerts.push(...this.certs); - retdss.crls.push(...this.crls); - this.cChain = new CertChain(checkCerts,pram); - if(!this.cChain){ - throw 0; - } - await this.cChain.getChains(); - const allCert = this.cChain.getCerts(); - if(!allCert){ - const _invalidPems = this.cChain.getInvalidCerts()||[]; - throw new Error('Cert trust chain not found.'+"\r\n"+_invalidPems.map(v=>v.subjectString).join("\r\n")); - } - for(const cert of allCert){ - const x509 = new X509(buffer2Hex(cert)); - const certId:CertId = (()=>{ - try{ - return { - "issuer":x509.getIssuerHex(), - "sn":x509.getSerialNumberHex(), - } - }catch(e){ - throw new Error('Unsupport cert file.') - } - })(); - if(!certs.find(v=>{ - if(v.issuer === certId.issuer && v.sn === certId.sn){ - return true; - } - })){ - certs.push(certId); - const _buf = hex2buffer(x509.hex); - if(_buf){ - retdss.certs.push(_buf); - } - const _dss = await this._getDSS(x509); - retdss.certs.push(..._dss.certs); - retdss.ocsps.push(..._dss.ocsps); - retdss.crls.push(..._dss.crls); - } - } - //check - SignTool.LOG.debug("DSS Check"); - const crlCheck = this.cChain.checkCRL(retdss.crls,this.signInfo); - const ocspCheck = this.cChain.checkOCSP(retdss.ocsps); - if(retdss.certs.length !== crlCheck.length || retdss.certs.length !== ocspCheck.length){ - throw new Error("DSS check certs error"); - } - const invalidCerts = []; - SignTool.LOG.debug('CRL,OCSP Valid result'); - for(let idx =0;idx0){ - throw new Error('DSS invalid.') - } - return retdss; - } - private _getDSS = async (subjectCertX509:X509) => { - const retdss:DSSTable = { - certs:[], - ocsps:[], - crls:[], - } - if(!this.cChain){ - throw 0; - } - const cdpList = subjectCertX509.getExtCRLDistributionPoints(); - for(const cdp of cdpList?.array||[]){ - if(!cdp.dpname){ - continue; - } - const uriList:Array = cdp.dpname.full.map(v=>v.uri); - for(const uri of uriList){ - const _url = new URL(uri); - if(_url){ - SignTool.LOG.debug(`Get CRL:${_url.href}`) - const crl = await axios({url:_url.href,responseType:"arraybuffer",}); - if(crl.status !== 200){ - throw new Error(`Request ${_url.href} is response error.(code:${crl.status})`) - }else{ - retdss.crls.push(SignTool.getCrl(crl.data)); - } - } - } - } - const AIAInfo = subjectCertX509.getExtAIAInfo(); - if(AIAInfo && Array.isArray(AIAInfo.ocsp)){ - for(let i=0;i { - SignTool.LOG = new Log(debug?1:9); - } - static getHash = (buf:Uint8Array,alg:JSRSASIGN_SupportHashAlg) => { - const hex = buffer2Hex(buf); - const md = new KJUR.crypto.MessageDigest({alg:alg}); - md.updateHex(hex); - const digest = md.digest(); - return digest; - } - - static getSHA1 = (buf:Uint8Array):string=>{ - return SignTool.getHash(buf,"sha1"); - } - - static getSignedHex = async ( - signer:{cert:Uint8Array,key:Uint8Array,passphrase?:string,caCerts?:Array}, - target:Uint8Array, - options?:IgetSignedHexOptions):Promise=>{ - SignTool.LOG.debug("getSignedHex") - const certObj = new X509(buffer2Hex(signer.cert)); - const issuer = {str: certObj.getIssuer().str, serial: certObj.getSerialNumberHex()}; - const keyObj = KEYUTIL.getKey(buffer2Hex(signer.key),signer.passphrase,"pkcs8prv"); - const keyType = keyObj.type==='EC'?'ECDSA':keyObj.type; - const hashAlg = options?.hashalg||defaultHashAlgoritm; - const signAlg = `${hashAlg.toUpperCase()}with${keyType}`; - const targetHash = SignTool.getHash(target,hashAlg); - const params:{certs:string[]} & SignPrams = { - version: 1, - hashalgs: [hashAlg], - econtent: { - type: "data", - content: { - hex: '', - }, - isDetached: true - }, - certs: [certHex2PEM(certObj.hex)], - sinfos: [{ - version: 1, - id: {type:'isssn', issuer: {str: issuer.str}, serial: {hex: issuer.serial}}, - hashalg: hashAlg, - sattrs: {array: [{ - attr: "contentType", - type: '1.2.840.113549.1.7.1', - },{ - attr: "signingTime", - str: SignTool.getTimeStr(), - },{ - attr: "messageDigest", - hex: targetHash, - },{ - attr:"signingCertificateV2", - array:[certObj.hex], - } - ]}, - sigalg: signAlg, - signkey:keyObj, - }], - fixed: true - }; - if(signer.caCerts){ - params.certs.push(...signer.caCerts.map(v=>certHex2PEM(new X509(buffer2Hex(v)).hex))); - } - if(options?.tsa){ - SignTool.LOG.debug("Cert embeddedTimeStamp"); - const signedData = new KJUR.asn1.cms.SignedData(params); - const cmsParser = new KJUR.asn1.cms.CMSParser(); - const _pram = cmsParser.getCMSSignedData(signedData.getContentInfoEncodedHex()); - const signedHash = _pram.sinfos[0].sighex; - if(!signedHash){ - throw new Error(`SignatureValue not found`); - } - const tstInfoHex = await SignTool.getTsaSigneture(hex2buffer(signedHash),options.tsa.hashalg||defaultHashAlgoritm,{url:options.tsa.URL}); - if(!signedData.params.sinfos[0].uattrs?.array){ - signedData.params.sinfos[0].uattrs = {array:[{attr:"timeStampToken",tst:tstInfoHex}]} - }else{ - signedData.params.sinfos[0].uattrs.array.push({attr:"timeStampToken",tst:tstInfoHex}); - } - return signedData.getContentInfoEncodedHex(); - }else{ - const sidnedData = new KJUR.asn1.cms.SignedData(params); - return sidnedData.getContentInfoEncodedHex(); - } - } - public static getTsaSigneture = async (signTrg:Uint8Array,tsaHashAlg:SupportHashAlgorithm,tsaServer:{url:string}):Promise => { - try{ - const nonceHex = KJUR.crypto.Util.getRandomHexOfNbits(32); - const reqNonce = nonceHex.substring(/[1-9]/.exec(nonceHex)?.index||0); - const sidnedDataHash = SignTool.getHash(signTrg,tsaHashAlg); - const tsreqPram:TimeStampReqPram = { - messageImprint: {alg:tsaHashAlg, hash: sidnedDataHash}, - nonce: {hex:reqNonce.length%2?`0${reqNonce}`:reqNonce}, - certreq: true, - }; - const tsaReqData = new KJUR.asn1.tsp.TimeStampReq(tsreqPram); - //TSA Request - SignTool.LOG.debug(`Request TSA:${tsaServer.url}`); - const tsaReq = await axios({ - "url":tsaServer.url, - "method":"POST", - "data":hex2buffer(tsaReqData.getEncodedHex()), - "responseType":"arraybuffer", - "headers":{"Content-Type":"application/timestamp-query"} - }) - if(tsaReq.status !== 200){ - throw new Error(`TSA request error [${tsaReq.status}]\r\n${tsaReq.data}`) - } - const parser = new KJUR.asn1.tsp.TSPParser(); - const tstRes = parser.getResponse(buffer2Hex(tsaReq.data)); - if(tstRes.statusinfo === "granted"|| (typeof tstRes.statusinfo !=="string" && tstRes.statusinfo?.status === "granted")){ - const _resnonceHex = tstRes.econtent?.content?.nonce?.hex; - if(!_resnonceHex){ - throw new Error(`TSA response nonce invalid.`); - } - const resNonce = _resnonceHex.substring(/[1-9]/.exec(_resnonceHex)?.index||0); - if(reqNonce.toLowerCase() === resNonce.toLowerCase()){ - const tstInfoObj = ASN1HEX.parse(buffer2Hex(tsaReq.data)); - if(tstInfoObj.seq){ - return KJUR.asn1.ASN1Util.jsonToASN1HEX(tstInfoObj.seq[1]); - } - throw new Error(`TSA response invalid format.`); - }else{ - throw new Error(`TSA response nonce invalid.`); - } - }else if(tstRes.status === "rejection"){ - throw new Error(`TSA reject request.`); - }else{ - throw new Error(`Unsupport format response.`); - } - }catch(e){ - throw new Error("Request TSA server Failed.") - } - } - - private static getTimeStr = () =>{ - const n = new Date(); - return `${n.getUTCFullYear().toString().slice(2).padStart(2,'0')}${(n.getUTCMonth()+1).toString().padStart(2,'0')}${n.getUTCDate().toString().padStart(2,'0')}${n.getUTCHours().toString().padStart(2,'0')}${n.getUTCMinutes().toString().padStart(2,'0')}${n.getUTCSeconds().toString().padStart(2,'0')}Z`; - } - public static DSS = DSS; - public static getCert = (cert:string|Uint8Array) => { - try{ - if(typeof cert === "string"){ - return hex2buffer(new X509(cert).hex); - }else{ - const str = buffer2Str(cert); - if(str.includes("-----BEGIN")){ - return hex2buffer(new X509(str).hex); - }else{ - return hex2buffer(new X509(buffer2Hex(cert)).hex); - } - } - }catch(e){ - throw new Error('Unsupport Certificate file.'); - } - } - public static chekCertUsage = (cert:Uint8Array) => { - try{ - const x509 = new X509(buffer2Hex(cert)); - const usage = x509.getExtKeyUsage(); - const usageEx = x509.getExtExtKeyUsage(); - if(!usage && !usageEx){ - return true; - } - if(([...usage?usage.names:[],...usageEx?usageEx.array:[]].includes("digitalSignature"))){ - return true; - }; - return false; - }catch(e){ - throw new Error("Unsupport cert file."); - } - - } - public static getKey = (key:string|Uint8Array,pass?:string) => { - try{ - if(typeof key === "string"){ - return hex2buffer(pemtohex(KEYUTIL.getPEM(KEYUTIL.getKey(key,pass),"PKCS8PRV"))); - }else{ - const str = buffer2Str(key); - if(str.includes("-----BEGIN")){ - return hex2buffer(pemtohex(KEYUTIL.getPEM(KEYUTIL.getKey(str,pass),"PKCS8PRV"))); - }else{ - return hex2buffer(pemtohex(KEYUTIL.getPEM(KEYUTIL.getKey(buffer2Hex(key),pass),"PKCS8PRV"))); - } - } - }catch(e){ - throw new Error('Unsupport KEY file.'); - } - } - public static getCrl = (crl:string|Uint8Array) => { - try{ - if(typeof crl === "string"){ - return hex2buffer(new X509CRL(crl).hex); - }else{ - const str = buffer2Str(crl); - if(str.includes("-----BEGIN")){ - return hex2buffer(new X509CRL(str).hex); - }else{ - return hex2buffer(new X509CRL(buffer2Hex(crl)).hex); - } - } - }catch(e){ - throw new Error('Unsupport CRL file.'); - } - } -} -const certHex2PEM = (h:string) => { - return KJUR.asn1.ASN1Util.getPEMStringFromHex(h,"CERTIFICATE") -} -const getBufferFromUrl = async (url:string) => { - try{ - const httpResponse = await axios({url:url,responseType:"arraybuffer",}); - if(httpResponse.status !== 200){ - throw new Error(`Request ${url} is response error.(code:${httpResponse.status})`) - } - return httpResponse.data as Uint8Array; - }catch(e){ - if(typeof e === "string"){ - throw new Error(e); - }else if(e instanceof AxiosError){ - throw new Error(e.message) - }else{ - throw new Error(`${url} request unknow error`); - } - } -} \ No newline at end of file diff --git a/src/spdf.ts b/src/spdf.ts index 56a9a9a..6e2637a 100644 --- a/src/spdf.ts +++ b/src/spdf.ts @@ -1,18 +1,5 @@ -import {PDFNumber,PDFHexString,PDFString,PDFName,PDFObject, PDFRef, rotateDegrees, translate, drawImage, degrees, drawText, rgb, toUint8Array, PDFContentStream, StandardFonts, PDFAcroSignature, PDFArray,PDFDict,Color,PDFRawStream,escapeRegExp, PDFPage} from "pdf-lib"; -import fontkit from '@pdf-lib/fontkit'; -import {SignTool,IgetSignedHexOptions, DSSTable} from "./signTool"; -import {buffer2Str,buffer2Hex,hex2buffer,imageFormatMagic,Log,convertCoord} from "./utils"; -import {PDFDocument,UserPermission} from "./pdf-lib_patch"; - -const DEFAULT_BYTE_RANGE_PLACEHOLDER = '**********'; -const SUBFILTER_ADOBE_PKCS7_DETACHED = 'adbe.pkcs7.detached'; -const SUBFILTER_ADOBE_PKCS7_SHA1 = 'adbe.pkcs7.sha1'; -const SUBFILTER_ADOBE_X509_SHA1 = 'adbe.x509.rsa.sha1'; -const SUBFILTER_ETSI_CADES_DETACHED = 'ETSI.CAdES.detached'; -const SUBFILTER_ETSI_RFC3161 = 'ETSI.RFC3161'; - -const Prop_BuilderName = "SPDF.js"; -const defaultHashAlgoritm = 'sha256'; +import {PDFObject} from "pdf-lib"; +import {PDFDocument} from "./pdf-lib_patch"; interface LiteralObject { [name: string]: Literal | PDFObject; @@ -28,1198 +15,7 @@ type Literal = | boolean | null | undefined; -type LockFiled = { - action:"All" -}|{ - action:"Include"|"Exclude", - fileds:Array, -} -type DocMDPPermssion = 1|2|3; -type SupportHashAlgorithm = 'sha1'|'sha256'|'sha384'|'sha512'; -interface TsaServer{ - url:string, - hashAlg?:SupportHashAlgorithm, - certSize?:number, -} -interface encryptOptions{ - userPassword:string, - ownerPassword:string, - permission:UserPermission, - keyBits:128|256, -} -interface pdfSignOptions{ - hashAlg?:SupportHashAlgorithm, - openPassword?:string, - signer?:{ - Name?:string, - Location?:string, - Reason?:string, - ContactInfo?:string, - }, - signature?:{ - page:number, - rect:{x:number,y:number,w:number,h:number}, - text?:{txt:string,size?:number,x?:number,y?:number,color?:Color,fontdata?:Uint8Array}, - image?:Uint8Array, - reverseImgTxt?:boolean, - }, - embeddedTimeStamp?:TsaServer; -} - -interface newSignOptions extends pdfSignOptions{ - encrypt?:encryptOptions, - DocMDP?:DocMDPPermssion, - lock?:LockFiled, -} -interface inclumentalSignOptions extends pdfSignOptions{ - lock?:LockFiled, -} -interface addDssOptions{ - openPassword?:string, - caCerts?:Array, - crls?:Array, - ignoreMissingTrustChain?:boolean, - ignoreRevokedCert?:boolean, - tsa:TsaServer, -} -interface timeStampOptions { - openPassword?:string, - tsa:TsaServer, -} -interface internalOptions extends pdfSignOptions{ - lock?:LockFiled, - DocMDP?:DocMDPPermssion, - embeddedTimeStamp?:TsaServer, - ignoreMissingTrustChain?:boolean, - ignoreRevokedCert?:boolean, - tsa?:TsaServer, - caCerts?:Array, - crls?:Array, - encrypt?:encryptOptions, -} -interface CERTIFICATEs{ - signer:{cert:string|Uint8Array,key:string|Uint8Array,keyPass?:string}, - caCerts?:Array, -} -interface crossReferenceTableRef{number:number,pos:number,gen:number,use:string} -type crossReferenceTableArray = Array; -class CrossReferenceTable{ - private table:crossReferenceTableArray; - constructor(table:crossReferenceTableArray){ - this.table = table; - } - private _defragmentSection(){ - const unfragmentTable:crossReferenceTableArray = []; - let zeroObj = false; - let lastDeleteObj:crossReferenceTableRef|null = null; - for(let i=0;i0){ - xrefTabl += `${no}`; - skip=0; - } - contin++ - tablTemp += `${ref.pos.toString().padStart(10,'0')} ${ref.gen.toString().padStart(5,'0')} ${ref.use} \x0a`; - }else{ - if(contin>0){ - xrefTabl += ` ${contin.toString()} \x0a${tablTemp}`; - tablTemp = ""; - contin = 0; - } - tablTemp = ""; - skip++; - } - } - xrefTabl += ` ${contin} \x0a${tablTemp}`; - return xrefTabl; - } -} -const regFNandNum = new RegExp("[0123456789fn]"); -const regEndOfLine = new RegExp("[\x0D\x0A]"); -const regSpace = new RegExp("[\x20]"); -type SingType = 0|1|2; -const singType = { - none:0 as SingType, - signeture:1 as SingType, - timestamp:2 as SingType, -} -export class pdfSigner{ - private signerCert?:{cert:Uint8Array,key:Uint8Array}; - private caCert?:Array; - private dssCerts?:Array; - private modeFlags:{ - singType:SingType; - incremental:boolean; - timestamp:boolean; - dss:0|1|2; - } - private signerCertSize:number; - private assumptionSignatureSize:number; - private pdf?:{ - buf:Uint8Array, - data:PDFDocument, - } - private originalPdf?:PDFDocument; - private modPdfBuf?:Uint8Array; - private options?:internalOptions; - - private LOG:Log; - - constructor(options?:{debug?:boolean}){ - this.signerCertSize = 0; - this.caCert = []; - this.modeFlags = { - singType:singType.none, - incremental:false, - timestamp:false, - dss:0, - } - this.assumptionSignatureSize = 0; - this.LOG = new Log(options?.debug?1:9); - SignTool.setdebug(options?.debug); - - } - _setCerts = (signerCert:CERTIFICATEs) => { - if(signerCert){ - const _cert = SignTool.getCert(signerCert.signer.cert); - if(!SignTool.chekCertUsage(_cert)){ - throw new Error("Certificate is not usage 'digitalSignature'."); - } - const _key = SignTool.getKey(signerCert.signer.key,signerCert.signer.keyPass); - this.signerCert = { - cert:_cert, - key:_key, - } - if(signerCert.caCerts){ - this.caCert = []; - for(const caCrt of signerCert.caCerts){ - this.caCert.push(SignTool.getCert(caCrt)); - } - } - const caCertsLength = (()=>{ - if(!this.caCert){ - return 0; - }else{ - return this.caCert.map(v=>v.length).reduce((a,b)=>a+b,0); - } - })(); - this.signerCertSize = Math.ceil(512+this.signerCert.cert.length*0.75+caCertsLength*0.75); - } - } - _setDssCerts = (certs:Array) => { - this.dssCerts = []; - for(const _cert of certs){ - this.dssCerts.push(SignTool.getCert(_cert)); - } - } - - newSing = async (pdf:string | Uint8Array | ArrayBuffer,certs:CERTIFICATEs,options?:newSignOptions) => { - this._setCerts(certs); - this.modeFlags = { - singType:singType.signeture, - incremental:false, - timestamp:false, - dss:0, - } - this.options = options; - return await this._callPdfSign(toUint8Array(pdf)); - } - inculumentalSign = async (pdf:string | Uint8Array | ArrayBuffer,certs:CERTIFICATEs,options?:inclumentalSignOptions) => { - this._setCerts(certs); - this.modeFlags = { - singType:singType.signeture, - incremental:true, - timestamp:false, - dss:0, - } - this.options = options; - if(this.options?.caCerts){ - this._setDssCerts(this.options.caCerts); - } - return await this._callPdfSign(toUint8Array(pdf)); - } - addDSSAllCerts = async (pdf:string | Uint8Array | ArrayBuffer,options?:addDssOptions) => { - this.modeFlags = { - singType:singType.timestamp, - incremental:true, - timestamp:true, - dss:1, - } - this.options = options; - if(this.options?.caCerts){ - this._setDssCerts(this.options.caCerts); - } - return await this._callPdfSign(toUint8Array(pdf)); - } - addDSSLastTimeStamp = async (pdf:string | Uint8Array | ArrayBuffer,options?:addDssOptions) => { - this.modeFlags = { - singType:singType.timestamp, - incremental:true, - timestamp:true, - dss:2, - } - this.options = options; - if(this.options?.caCerts){ - this._setDssCerts(this.options.caCerts); - } - return await this._callPdfSign(toUint8Array(pdf)); - } - inculumentalTimeStamp = async (pdf:string | Uint8Array | ArrayBuffer,tsaPram:timeStampOptions) => { - this.modeFlags = { - singType:singType.timestamp, - incremental:true, - timestamp:true, - dss:0, - } - this.options = tsaPram; - return await this._callPdfSign(toUint8Array(pdf)); - } - - private _callPdfSign = async (pdfBuf:Uint8Array) => { - const assumptionTsaCertSize = (this.options && (this.options.embeddedTimeStamp || this.options.tsa))?this.options?.tsa?.certSize||6144:0; - this.assumptionSignatureSize = this.signerCertSize + assumptionTsaCertSize; - if(this.modeFlags.incremental){ - this.pdf = { - buf:pdfBuf, - data:await PDFDocument.load( - pdfBuf - ,typeof this.options?.openPassword === "string" - ?{"password":this.options?.openPassword,unRemoveEncryptDic:true,reqPermissions:{"modifying":true,"annotating":true}} - :undefined), - } - }else{ - this.pdf = { - buf:new Uint8Array(pdfBuf), - data:await PDFDocument.load( - new Uint8Array(pdfBuf) - ,typeof this.options?.openPassword === "string" - ?{"password":this.options?.openPassword,"updateMetadata":false} - :{"updateMetadata":false}), - } - } - const _returnBuf = await this._pdfSign(); - if(typeof _returnBuf === "number"){ - //Contents was not size enough, so it was enlarged and reprocessed. - this.assumptionSignatureSize = _returnBuf+64; - if(this.modeFlags.incremental){ - this.pdf = { - buf:pdfBuf, - data:await PDFDocument.load( - pdfBuf - ,typeof this.options?.openPassword === "string" - ?{"password":this.options?.openPassword,unRemoveEncryptDic:true,reqPermissions:{"modifying":true,"annotating":true}} - :undefined), - } - }else{ - this.pdf = { - buf:new Uint8Array(pdfBuf), - data:await PDFDocument.load( - new Uint8Array(pdfBuf) - ,typeof this.options?.openPassword === "string" - ?{"password":this.options?.openPassword,"updateMetadata":false} - :{"updateMetadata":false}), - } - } - const _returnBuf2 = await this._pdfSign(); - if(typeof _returnBuf2 === "number"){ - throw new Error(`Add sign error`); - }else{ - return _returnBuf2; - } - }else{ - return _returnBuf; - } - } - - private _pdfSign = async () =>{ - if(!this.pdf){ - throw new Error('PDFDocument not loaded.'); - } - const sigName = await this._addSignatureObject(); - if(this.modeFlags.incremental){ - this.originalPdf = await PDFDocument.load(this.pdf.buf - ,typeof this.options?.openPassword === "string" - ?{"password":this.options?.openPassword,"updateMetadata":false,unRemoveEncryptDic:true,reqPermissions:{"modifying":true,"annotating":true}} - :{"updateMetadata":false}); - this.modPdfBuf = await this._pdflibIncrementalUpdates(); - }else{ - this.modPdfBuf = await this._deFragmentXREF(); - } - if(!this.modPdfBuf){ - throw new Error('Add placeholder fail.'); - } - if(!this.modeFlags.singType){ - return this.modPdfBuf; - } - const signedPdf = await this._addsign(sigName); - if(!signedPdf){ - throw new Error(`Add sign error`); - }else{ - return signedPdf; - } - } - private _addSignatureObject = async () =>{ - if(!this.pdf){ - throw new Error('PDFDocument not loaded.'); - } - const pdfData = this.pdf?.data; - const signs:Array = []; - const singRefs:Array = []; - const emmbedCerts:Array = []; - for(const obj of pdfData.catalog.getOrCreateAcroForm().getAllFields()){ - if(obj[0] instanceof PDFAcroSignature){ - const sigT = obj[0].T(); - if(sigT){ - singRefs.push(obj[1]); - signs.push(sigT instanceof PDFString?sigT.toString():sigT.decodeText()); - } - const sigV = obj[0].V(); - if(this.modeFlags.dss === 1 && sigV instanceof PDFDict){ - const certContents = sigV.get(PDFName.of("Contents")); - if(certContents instanceof PDFHexString){ - const certContent = hex2buffer(certContents.toString().slice(1).slice(0,-1)); - if(!certContent){ - throw new Error('Embbed cert read error'); - } - let lastZero=0; - for(let p=certContent.length-1;p>0;p--){ - if(certContent[p] !==0){ - lastZero = p; - break; - } - } - emmbedCerts.push(certContent.slice(0,lastZero+1)); - } - } - } - } - const newSingT = (()=>{ - let i = 1; - while(signs.includes(`(Signature${i})`)){ - i++; - } - return `Signature${i}`; - })(); - const pages = pdfData.getPages(); - const pageIndex = (this.options?.signature?.page && this.options.signature.page > 0)?this.options.signature.page-1:0; - const ByteRange = PDFArray.withContext(pdfData.context); - ByteRange.push(PDFName.of(newSingT.padEnd(10,"*"))); - ByteRange.push(PDFName.of(DEFAULT_BYTE_RANGE_PLACEHOLDER)); - ByteRange.push(PDFName.of(DEFAULT_BYTE_RANGE_PLACEHOLDER)); - ByteRange.push(PDFName.of(DEFAULT_BYTE_RANGE_PLACEHOLDER)); - const sigPram:LiteralObject =this.modeFlags.singType === singType.timestamp?{ - Type: 'DocTimeStamp', - Filter: 'Adobe.PPKLite', - SubFilter: SUBFILTER_ETSI_RFC3161, - ByteRange, - Contents: PDFHexString.of(newSingT+'0'.repeat((this.assumptionSignatureSize-newSingT.length)*2)), - Prop_Build:pdfData.context.obj({App:pdfData.context.obj({Name:Prop_BuilderName})}), - } - :{ - Type: 'Sig', - Filter: 'Adobe.PPKLite', - SubFilter: SUBFILTER_ADOBE_PKCS7_DETACHED, - ByteRange, - Contents: PDFHexString.of(newSingT+'0'.repeat((this.assumptionSignatureSize-newSingT.length)*2)), - M: PDFString.fromDate(new Date()), - Prop_Build:pdfData.context.obj({App:pdfData.context.obj({Name:Prop_BuilderName})}), - } - if(this.options?.signer){ - for(const [key,val] of Object.entries(this.options.signer)){ - if(val){ - sigPram[key] = PDFString.of(val); - } - } - } - if(this.options?.DocMDP){ - //Create DocMDP Obj - const DocMDP = pdfData.context.obj({ - Type:'TransformParams', - P:PDFNumber.of(this.options.DocMDP), - V:'1.2', - }); - const signaturereference = pdfData.context.obj({ - Type:'SigRef', - TransformMethod:'DocMDP', - TransformParams:DocMDP, - }); - const array = PDFArray.withContext(pdfData.context); - array.push(signaturereference); - sigPram.Reference = array; - } - const signatureDict = pdfData.context.obj(sigPram); - const signatureDictRef = pdfData.context.register(signatureDict); - if(this.options?.DocMDP){ - //Link DocMDP - const catalog = pdfData.context.lookup(pdfData.context.trailerInfo.Root); - const Permission = pdfData.context.obj({ - DocMDP:signatureDictRef - }); - if(catalog){ - //@ts-ignore ; Non public method. - catalog.set(PDFName.of("Perms"), Permission); - } - } - interface wigitPram extends LiteralObject{Rect:Array} - const widgetDictPram:wigitPram = { - Type: 'Annot', - Subtype: 'Widget', - FT: 'Sig', - Rect: [0, 0, 0, 0], - V: signatureDictRef, - F: PDFNumber.of(getAnnotationFlags({Print:true,Hidden:false,NoView:false,Locked:true,LockedContents:true})), - T: PDFString.of(newSingT), - P: pages[pageIndex].ref, - DR:pdfData.context.obj({}), - } - if(this.options?.lock){ - if(this.options.lock.action === "All"){ - widgetDictPram.Lock = pdfData.context.register(pdfData.context.obj({ - Type:"SigFieldLock", - Action:"All", - P:1, - })); - } - if(this.options.lock.action === "Include"){ - const _filed = PDFArray.withContext(pdfData.context); - for(const fname of this.options.lock.fileds){ - _filed.push(PDFString.of(fname)); - } - widgetDictPram.Lock = pdfData.context.register(pdfData.context.obj({ - Type:"SigFieldLock", - Action:"Include", - P:1, - Fields:_filed, - })); - } - if(this.options.lock.action === "Exclude"){ - const _filed = PDFArray.withContext(pdfData.context); - for(const fname of this.options.lock.fileds){ - _filed.push(PDFString.of(fname)); - } - widgetDictPram.Lock = pdfData.context.register(pdfData.context.obj({ - Type:"SigFieldLock", - Action:"Exclude", - P:1, - Fields:_filed, - })); - } - } - if(this.options?.signature){ - //add visible sign - //widgetDict - const _o = this.options.signature; - const imgFormat = imageFormatMagic(_o.image); - const coordConverter = new convertCoord(pages[pageIndex].getSize()); - const pos = coordConverter.convertXY({x:_o.rect.x||0,y:_o.rect.y||0}); - widgetDictPram.Rect[0] = pos.xPt; - widgetDictPram.Rect[1] = pos.yPt; - widgetDictPram.Rect[2] = pos.xPt+coordConverter.convertMm2Pt(_o.rect.w); - widgetDictPram.Rect[3] = pos.yPt-coordConverter.convertMm2Pt(_o.rect.h); - const visibleSignObj = await this._makeSigObj(pages[pageIndex],{ - "x":_o.rect.x, - "y":_o.rect.y, - "height":_o.rect.h, - "width":_o.rect.w,}, - { - "image":_o.image&&imgFormat?{ - "data":_o.image, - "format":imgFormat, - }:undefined, - "text":(_o.text?.txt)?{ - "font":_o.text.fontdata, - "txt":_o.text.txt, - "size":_o.text.size, - }:undefined - } - ); - widgetDictPram.AP = pdfData.context.obj({N:visibleSignObj}); - } - const widgetDict = pdfData.context.obj(widgetDictPram); - const widgetDictRef = pdfData.context.register(widgetDict); - pages[pageIndex].node.set(PDFName.of('Annots'), pdfData.context.obj([...(this.modeFlags.incremental?singRefs:[]),widgetDictRef])); - const sigFlag = pdfData.catalog.getOrCreateAcroForm().dict.lookup(PDFName.of('SigFlags')); - if(this.modeFlags.incremental && sigFlag){ - pdfData.catalog.getOrCreateAcroForm().addField(widgetDictRef); - }else{ - pdfData.catalog.set( - PDFName.of('AcroForm'), - pdfData.context.obj({ - SigFlags: 3, - Fields: [widgetDictRef], - }), - ); - } - if(this.modeFlags.dss){ - if(this.modeFlags.dss === 2){ - const lastTsCert = this._lastTimeStamp(this.pdf.buf); - if(!lastTsCert){ - throw new Error('Last timestamp not found.') - } - const lastTsCertBuf = hex2buffer(lastTsCert); - if(!lastTsCertBuf){ - throw new Error('Last timestamp contents unsupport data.') - } - emmbedCerts.push(lastTsCertBuf); - } - const chainCheckFlag = this.options?.ignoreMissingTrustChain?true:false; - const revokeCheckFlag = this.options?.ignoreRevokedCert?true:false; - const dssObj = new SignTool.DSS(); - if(this.options?.crls){ - dssObj.importCRLs(this.options.crls); - } - if(this.dssCerts){ - dssObj.importCerts(this.dssCerts); - } - this.LOG.debug(`Emmbed cert ${emmbedCerts.length} nums`); - dssObj.fetchSignerCerts(emmbedCerts); - const _setDss:DSSTable = await dssObj.getDSSTable({ignoreMissingTrustChain:chainCheckFlag,ignoreRevokedCert:revokeCheckFlag}); - await this._addDss(_setDss); - } - pdfData.setModificationDate(new Date()); - return newSingT; - } - private _makeSigObj = async (pdfPage:PDFPage,box:{width?:number,height?:number,rotaion?:number,x?:number,y?:number}, - data:{image?:{format:"JPEG"|"PNG",data:Uint8Array}, - text?:{txt:string,size?:number,font?:Uint8Array}})=>{ - const coordConverter = new convertCoord(pdfPage.getSize()); - const pos = coordConverter.convertXY({x:box.x||0,y:box.y||0}); - const dictBox = { - rotaion:box.rotaion||0, - width:coordConverter.convertMm2Pt(box.width||0), - height:coordConverter.convertMm2Pt(box.height||0), - x:pos.xPt, - y:pos.yPt, - } - if(!this.pdf){ - throw new Error('PDFDocument not loaded.'); - } - const pdfData = this.pdf.data; - const image = data.image; - const text = data.text; - const imagePdf = await (async ()=>{ - if(image){ - if(image.format === "JPEG"){ - return pdfData.embedJpg(image.data); - } - if(image.format === "PNG"){ - return pdfData.embedPng(image.data); - } - } - //Dummy 1x1 PNG. - return pdfData.embedPng("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQI12NgAAIAAAUAAeImBZsAAAAASUVORK5CYII="); - })(); - pdfData.registerFontkit(fontkit); - const fontObj = await pdfData.embedFont(text?.font||StandardFonts.Courier,{"subset":true}); - const resorce = { XObject: { Image: imagePdf.ref }} as {XObject:{ Image: PDFRef },Font?:{[fname:string]:PDFRef}}; - if(fontObj){ - resorce.Font = {F0:fontObj.ref}; - } - const dict = imagePdf.doc.context.obj({ - Type: 'XObject', - Subtype: 'Form', - FormType: 1, - BBox: [0, 0,dictBox.width, dictBox.height], - Resources: resorce, - }); - const opt = [ - rotateDegrees(dictBox.rotaion), - translate(0, dictBox.rotaion % 90 === 0 ? - dictBox.width : 0), - ] - const imageOperater = [...drawImage('Image',{ - x:0, - y:dictBox.height, - width:dictBox.width, - height:dictBox.height, - rotate:degrees(0), - xSkew:degrees(0), - ySkew:degrees(0), - }), - ]; - const textOperater = (text && fontObj)?[...drawText(fontObj.encodeText(text.txt),{ - color: this.options?.signature?.text?.color||rgb(0, 0, 0), - font: 'F0', - size: text.size||10, - rotate: degrees(0), - xSkew: degrees(0), - ySkew: degrees(0), - x: 0+coordConverter.convertMm2Pt(this.options?.signature?.text?.x||0), - y: dictBox.height-coordConverter.convertMm2Pt(this.options?.signature?.text?.y||0), - })]:[]; - if(this.options?.signature?.reverseImgTxt){ - opt.push(...textOperater); - opt.push(...imageOperater); - }else{ - opt.push(...imageOperater); - opt.push(...textOperater); - } - const stream = PDFContentStream.of(dict,opt,false); - return imagePdf.doc.context.register(stream); - } - private _addDss = async (dss:DSSTable) =>{ - if(!this.pdf){ - throw new Error('PDFDocument not loaded.'); - } - const pdfData = this.pdf.data; - let dssPram:Literal = { - Type:"DSS" - } - const dssDict = (()=>{ - if(pdfData.catalog.lookup(PDFName.of('DSS'))){ - return pdfData.catalog.lookup(PDFName.of('DSS')) - }else{ - const dict = pdfData.context.obj(dssPram); - pdfData.catalog.set(PDFName.of('DSS'),pdfData.context.register(dict)); - return dict; - } - })(); - if(dss.crls){ - const dic = (()=>{ - //@ts-ignore - if(dssDict?.dict?.get(PDFName.of('CRLs'))){ - //@ts-ignore - return pdfData.context.lookup(dssDict?.dict?.get(PDFName.of('CRLs'))); - }else{ - const dict = PDFArray.withContext(pdfData.context); - //@ts-ignore - dssDict.set(PDFName.of('CRLs'),pdfData.context.register(dict)); - return dict; - } - })(); - if(!dic){ - throw new Error('DSS Dict create error.'); - } - for(const data of dss.crls){ - //@ts-ignore - dic.array.push(pdfData.context.register(pdfData.context.flateStream(data))); - } - } - if(dss.ocsps){ - const dic = (()=>{ - //@ts-ignore - if(dssDict?.dict?.get(PDFName.of('OCSPs'))){ - //@ts-ignore - return pdfData.context.lookup(dssDict?.dict?.get(PDFName.of('OCSPs'))); - }else{ - const dict = PDFArray.withContext(pdfData.context); - //@ts-ignore - dssDict.set(PDFName.of('OCSPs'),pdfData.context.register(dict)); - return dict; - } - })(); - if(!dic){ - throw new Error('DSS Dict create error.'); - } - for(const data of dss.ocsps){ - //@ts-ignore - dic.array.push(pdfData.context.register(pdfData.context.flateStream(data))); - } - } - if(dss.certs){ - const dic = (()=>{ - //@ts-ignore - if(dssDict?.dict?.get(PDFName.of('Certs'))){ - //@ts-ignore - return pdfData.context.lookup(dssDict?.dict?.get(PDFName.of('Certs'))); - }else{ - const dict = PDFArray.withContext(pdfData.context); - //@ts-ignore - dssDict.set(PDFName.of('Certs'),pdfData.context.register(dict)); - return dict; - } - })(); - if(!dic){ - throw new Error('DSS Dict create error.'); - } - for(const data of dss.certs){ - //@ts-ignore - dic.array.push(pdfData.context.register(pdfData.context.flateStream(data))); - } - } - return; - } - private _deFragmentXREF = async () => { - // If DocMDP is enabled, the signature will be invalidated if the xref (Cross-Reference Table) section is split, so this is avoided. - // Same as if the Cross-ReferenceTable section of the original PDF is separated when adding signatures with incremental updates. - if(!this.pdf){ - throw new Error('PDFDocument not loaded.'); - } - if(this.options?.encrypt){ - await this.pdf.data.encrypt({ - userPassword:this.options.encrypt.userPassword, - ownerPassword:this.options.encrypt.ownerPassword, - permission:this.options.encrypt.permission, - keyBits:this.options.encrypt.keyBits, - }); - } - //saveしないとObjectが確定しない - const _pdfBuf = await this.pdf.data.save({"useObjectStreams":false}); - const xref = this._findXref(_pdfBuf); - if(!xref){ - throw new Error("Cross-Reference Table find fail"); - } - const xrefBuf = xref.table.toBuf(true); - const newLength = _pdfBuf.length-(xref.trailerPos-xref.pos)+xrefBuf.length; - const defragPdf = new Uint8Array(newLength); - defragPdf.set(_pdfBuf.slice(0,xref.pos)); - defragPdf.set(xrefBuf,xref.pos); - defragPdf.set(_pdfBuf.slice(xref.trailerPos),xref.pos+xrefBuf.length); - return defragPdf; - } - private _pdflibIncrementalUpdates = async ()=>{ - //Compare two PDFDocuments and incrementally update the differences - const orgPdf = this.originalPdf; - const updPdf = this.pdf?.data; - if(!orgPdf || !updPdf || !this.pdf){ - throw new Error('Inclumental update failed.') - } - await updPdf.save({"useObjectStreams":false}); - const originObject:{[tag:string]:[PDFRef,PDFObject]} = {}; - for(const obj of orgPdf.context.enumerateIndirectObjects()){ - originObject[obj[0].tag] = obj; - } - const updateObject:{[tag:string]:{ref:PDFRef,obj:PDFObject,pos:number}} = {}; - if(orgPdf.context._encrypt && !orgPdf.context._reEncrypt){ - throw new Error("unable Re-encrypt") - } - for(const obj of updPdf.context.enumerateIndirectObjects()){ - if(!originObject[obj[0].tag]){ - //New object - if(orgPdf.context._encrypt && orgPdf.context._reEncrypt){ - encryptValue(obj[0],obj[1],orgPdf.context._reEncrypt) - } - updateObject[obj[0].tag] = {ref:obj[0],obj:obj[1],pos:0}; - }else{ - //Mod object - const [orign,update] = [obj.toString(),originObject[obj[0].tag].toString()]; - if(orign.length !== update.length || orign !== update){ - if(orgPdf.context._encrypt && orgPdf.context._reEncrypt){ - encryptValue(obj[0],obj[1],orgPdf.context._reEncrypt) - } - updateObject[obj[0].tag] = {ref:obj[0],obj:obj[1],pos:0}; - } - } - } - const originEOF = this.pdf.buf.length; - const xrefTabArray:crossReferenceTableArray = [{number:0,pos:0,gen:65535,use:"f"}]; - const addData:Array = []; - const eooBuf = new TextEncoder().encode("\x0aendobj\x0a"); - let pos = originEOF+1; - for(const [tag,obj] of Object.entries(updateObject)){ - obj.pos = pos; - const tagBuf = new TextEncoder().encode(`${obj.ref.objectNumber} ${obj.ref.generationNumber} obj\x0a`); - const addObjBuf = new Uint8Array(tagBuf.length+obj.obj.sizeInBytes()+eooBuf.length); - addObjBuf.set(tagBuf); - addObjBuf.set(eooBuf,tagBuf.length+obj.obj.sizeInBytes()); - obj.obj.copyBytesInto(addObjBuf,tagBuf.length); - addData.push(addObjBuf); - xrefTabArray[obj.ref.objectNumber] = {number:obj.ref.objectNumber,"pos":pos,"gen":obj.ref.generationNumber,use:"n"}; - pos += addObjBuf.length; - } - const bodySize = addData.map(v=>v.length).reduce((a,b)=>a+b,0); - const bodyBuf = new Uint8Array(bodySize); - let bodyPos = 0; - for(const buf of addData){ - bodyBuf.set(buf,bodyPos); - bodyPos += buf.length; - } - //Cross-Reference Tabl - const xrefPos = pos; - const xrefTableBuf = (new CrossReferenceTable(xrefTabArray)).toBuf(); - //Trailer - const xref = this._findXref(this.pdf.buf); - if(!xref){ - throw new Error("Cross-Reference Table find fail"); - } - const prevRefPos = xref.pos; - const originalDocIDDic = orgPdf.context.trailerInfo.ID; - const originalDocID = (originalDocIDDic instanceof PDFArray)? - originalDocIDDic.asArray()[0].toString():`<${SignTool.getSHA1(this.pdf.buf).toUpperCase()}>` - //@ts-ignore; Non public propaty. - const trailerBuf = new TextEncoder().encode(`trailer\x0a<] >>\x0a`); - const eofBuf = new TextEncoder().encode(`startxref\x0a${xrefPos}\x0a%%EOF`); - const newPdf = new Uint8Array(1+this.pdf.buf.length+bodyBuf.length+xrefTableBuf.length+trailerBuf.length+eofBuf.length); - newPdf.set(this.pdf.buf); - newPdf[this.pdf.buf.length] = 0x0a; - newPdf.set(bodyBuf,1+this.pdf.buf.length); - newPdf.set(xrefTableBuf,1+this.pdf.buf.length+bodyBuf.length); - newPdf.set(trailerBuf,1+this.pdf.buf.length+bodyBuf.length+xrefTableBuf.length); - newPdf.set(eofBuf,1+this.pdf.buf.length+bodyBuf.length+xrefTableBuf.length+trailerBuf.length); - return newPdf; - } - private _addsign = async (sigName:string) =>{ - const sigSize = this.assumptionSignatureSize; - const modPdfBuf = this.modPdfBuf; - const cert = this.signerCert; - const caPEMs = this.caCert||[]; - if(!modPdfBuf){ - throw new Error('failed.'); - } - const sigObj = await this._pdfBinSigObj(modPdfBuf,sigName); - if(!sigObj){ - throw new Error('Signecture content update fail.'); - } - const signTargetArray = new Uint8Array(sigObj.byteRangeObj[1]+sigObj.byteRangeObj[3]); - signTargetArray.set(modPdfBuf.slice(sigObj.byteRangeObj[0],sigObj.byteRangeObj[1])); - signTargetArray.set(modPdfBuf.slice(sigObj.byteRangeObj[2]),sigObj.byteRangeObj[1]); - const signOption:IgetSignedHexOptions = {"hashalg":defaultHashAlgoritm} - if(this.options?.hashAlg){ - signOption.hashalg = this.options.hashAlg; - } - if(this.options?.embeddedTimeStamp){ - signOption.tsa = {"URL":this.options.embeddedTimeStamp.url} - signOption.tsa.hashalg = this.options.embeddedTimeStamp.hashAlg||defaultHashAlgoritm; - }else if(this.options?.tsa){ - signOption.tsa = {"URL":this.options.tsa.url} - signOption.tsa.hashalg = this.options.tsa.hashAlg||defaultHashAlgoritm; - } - if((this.modeFlags.timestamp || this.options?.embeddedTimeStamp) && !signOption.tsa){ - throw new Error('TSA option undefined'); - } - let signedcert:string|undefined; - if(this.modeFlags.singType === singType.signeture){ - if(!cert){ - throw new Error('SignerCert not set'); - } - signedcert = await SignTool.getSignedHex({cert:cert.cert,key:cert.key,caCerts:this.caCert},signTargetArray,signOption) - }else if(this.modeFlags.singType === singType.timestamp){ - signedcert = await SignTool.getTsaSigneture(signTargetArray,signOption.tsa?.hashalg as SupportHashAlgorithm,{url:signOption.tsa?.URL as string}) - } - if(signedcert){ - if(signedcert.length > sigSize*2){ - return signedcert.length/2; - } - const signecontent = `<${signedcert}`.padEnd(sigObj.contentLen-1,'0')+'>'; - const sContentArray = new TextEncoder().encode(signecontent); - const signedPdf = new Uint8Array(modPdfBuf.length); - signedPdf.set(modPdfBuf.slice(sigObj.byteRangeObj[0],sigObj.byteRangeObj[1])); - signedPdf.set(sContentArray,sigObj.byteRangeObj[1]); - signedPdf.set(modPdfBuf.slice(sigObj.byteRangeObj[2]),sigObj.byteRangeObj[2]); - return signedPdf; - } - return; - } - private _pdfBinSigObj = async (pdf:Uint8Array,sigName:string) => { - const sigObj = { - byteRangePos:{s:0,e:0}, - byteRangeObj:[0,0,0,0], - contentLen:-1, - } - const flag={ - inSig:0, - inByteRange:false, - inContents:false, - } - const trigerSize = sigName.length+24; - const byterangeTrigerReg = new RegExp(`^\\/ByteRange\\s*\\[\\s*\\/${sigName}\\**\\s*\\/`); - const contentsTrigerReg = new RegExp(`^\\/Contents\\s*<${sigName}00`); - for(let pos=0;pos'.codePointAt(0)){ - sigObj.byteRangeObj[2] = pos+1; - sigObj.byteRangeObj[3] = pdf.length - sigObj.byteRangeObj[2]; - sigObj.contentLen = sigObj.byteRangeObj[2]-sigObj.byteRangeObj[1]; - flag.inContents = false; - flag.inSig++; - } - continue; - } - } - const byteRageContent = `[0 ${sigObj.byteRangeObj[1]} ${sigObj.byteRangeObj[2]} ${sigObj.byteRangeObj[3]}]`.padEnd(sigObj.byteRangePos.e-sigObj.byteRangePos.s+1); - for(let i=sigObj.byteRangePos.s;i<=sigObj.byteRangePos.e;i++){ - pdf[i] = byteRageContent.codePointAt(i-sigObj.byteRangePos.s)||0; - } - return flag.inSig===2?sigObj:null; - } - private _findXref = (pdfBuf:Uint8Array) =>{ - let eof = -1; - let startxref = -1; - let xrefPos = -1; - let trailerPos = -1; - for(let p = pdfBuf.length;p>0;p--){ - if(pdfBuf[p] === 'F'.codePointAt(0) && p > 4){ - const keyword = buffer2Str(pdfBuf,p-4,5); - if(keyword === "%%EOF"){ - eof = p; - } - } - if(eof > 0 && pdfBuf[p] === 'f'.codePointAt(0) && p > 8){ - const keyword = buffer2Str(pdfBuf,p-8,9); - if(keyword === "startxref"){ - startxref = p; - } - } - if(startxref > 0 && pdfBuf[p] === 'r'.codePointAt(0) && p > 6){ - const keyword = buffer2Str(pdfBuf,p-6,7); - if(keyword === "trailer"){ - trailerPos = p-7; - break; - } - } - } - if(startxref > 0){ - let numberstart=false; - let xrefNum = ""; - for(let p=startxref;p=0 && s<=9){ - if(!numberstart){ - numberstart=true; - } - xrefNum+=s.toString(); - }else if(numberstart){ - break; - } - } - if(xrefNum){ - const xrefNumber = parseInt(xrefNum,10); - if(Number.isFinite(xrefNumber)){ - xrefPos = xrefNumber; - } - } - } - if(xrefPos > 0){ - const keyword = buffer2Str(pdfBuf,xrefPos,4); - const crossReferenceTable:crossReferenceTableArray = []; - if(keyword === "xref"){ - let step = 0; - let objectNumber = 0; - const refLine = ["","",""]; - for(let p=xrefPos+4;p{ - let eof = -1; - let typeDocTimeStamp = -1; - let objPos = -1; - for(let p = pdfBuf.length;p>0;p--){ - if(pdfBuf[p] === 'F'.codePointAt(0) && p > 4){ - const keyword = buffer2Str(pdfBuf,p-4,5); - if(keyword === "%%EOF"){ - if(eof > 0){ - return; - } - eof = p; - } - } - if(eof > 0 && pdfBuf[p] === 'p'.codePointAt(0) && p > 8){ - const keyword = buffer2Str(pdfBuf,p-11,12); - if(typeDocTimeStamp < 0 && keyword === "DocTimeStamp"){ - typeDocTimeStamp = p; - } - } - if(typeDocTimeStamp > 0 && pdfBuf[p] === 'j'.codePointAt(0) && p > 6){ - const keyword = buffer2Str(pdfBuf,p-3,4); - if(keyword === " obj"){ - objPos = p; - break; - } - } - } - if(objPos > 0){ - let contentsFlg = 0; - let contents = ""; - for(let p=objPos;p'.codePointAt(0)){ - contentsFlg = 0; - break; - } - } - } - } - return contents; - } - return; - } -} - -const getAnnotationFlags = (flags:{ - Invisible?:boolean, - Hidden?:boolean, - Print?:boolean, - NoZoom?:boolean, - NoRotat?:boolean, - NoView?:boolean, - ReadOnly?:boolean, - Locked?:boolean, - ToggleNoView?:boolean, - LockedContents?:boolean, -}) =>{ - return 0 - +(flags.Invisible?2**0:0) - +(flags.Hidden?2**1:0) - +(flags.Print?2**2:0) - +(flags.NoZoom?2**3:0) - +(flags.NoRotat?2**4:0) - +(flags.NoView?2**5:0) - +(flags.ReadOnly?2**6:0) - +(flags.Locked?2**7:0) - +(flags.ToggleNoView?2**8:0) - +(flags.LockedContents?2**9:0); -} -const encryptValue = (ref:PDFRef,object:PDFObject,getEncryptFn:any) =>{ - if(object instanceof PDFDict){ - //@ts-ignore - const type = object.dict.get(PDFName.of("Type")) as PDFName; - //@ts-ignore - for(const value of object.dict){ - if((type?.asString() === "/Sig" || type?.asString() === "/DocTimeStamp") && value[0].asString() === "/Contents"){ - //Skip SignContents - continue; - } - const encrypter = getEncryptFn(ref.objectNumber,ref.generationNumber); - if(value[1] instanceof PDFString){ - const valueBuffer = new Uint8Array(value[1].sizeInBytes()); - value[1].copyBytesInto(valueBuffer,0); - const data = encrypter(valueBuffer.subarray(1,valueBuffer.length-1)) as Uint8Array - //@ts-ignore , - value[1].value = escapeRegExp(buffer2Str(data)); - //@ts-ignore - value[1]._noEncode = true; - } - if(value[1] instanceof PDFHexString){ - const valueBuffer = value[1].asBytes(); - const data = encrypter(valueBuffer) - //@ts-ignore , - value[1].value = buffer2Hex(data); - } - if(value[1] instanceof PDFArray){ - for(const item of value[1].asArray()){ - encryptValue(ref,item,getEncryptFn); - } - } - if(value[1] instanceof PDFDict){ - encryptValue(ref,value[1],getEncryptFn); - } - } - } - if(object instanceof PDFRawStream){ - const encrypter = getEncryptFn(ref.objectNumber,ref.generationNumber); - const valueBuffer = object.asUint8Array(); - const data = encrypter(valueBuffer) - //@ts-ignore , - object.contents = data; - } - if(object instanceof PDFContentStream){ - const encrypter = getEncryptFn(ref.objectNumber,ref.generationNumber); - const valueBuffer = object.getContents(); - const data = encrypter(valueBuffer) - //@ts-ignore , - object.contentsCache.value = data; - } -} - -//PDF Encrypt Tool -export const encryptPDF = async (pdf: string | Uint8Array | ArrayBuffer,encryptOptions:encryptOptions) => { - const pdfDoc = await PDFDocument.load(pdf); - await pdfDoc.encrypt(encryptOptions); - return await pdfDoc.save({"useObjectStreams":false}); -} export const decryptPDF = async (pdf: string | Uint8Array | ArrayBuffer,ownerPassword:string) => { const pdfDoc = await PDFDocument.load(pdf,{"password":ownerPassword}); return await pdfDoc.save({"useObjectStreams":false}); diff --git a/src/utils.ts b/src/utils.ts index 3442dee..5f92911 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -14,9 +14,12 @@ export const str2Bufeer = (str:string) =>{ for(const c of Array.from(str)){ const code = c.charCodeAt(0); if(code<256){ + // @ts-ignore _str += code.toString(16).padStart(2,"0"); }else{ + // @ts-ignore _str += ((code&0xFF00)>>8).toString(16).padStart(2,"0"); + // @ts-ignore _str += ((code&0x00FF)).toString(16).padStart(2,"0"); } } @@ -28,6 +31,7 @@ export const buffer2Hex = (b:Uint8Array,pos?:number,len?:number) =>{ const _len = len||b.length; for(let i=0;i<_len;i++){ if(typeof b[_pos+i] === "number"){ + // @ts-ignore _str.push(b[_pos+i].toString(16).padStart(2,'0')) } } @@ -36,7 +40,7 @@ export const buffer2Hex = (b:Uint8Array,pos?:number,len?:number) =>{ export const hex2buffer = (hex:string) => { const hexMap = hex.match(/.{1,2}/g); if(!hexMap){ - return new Uint8Array(); + return new Uint8Array(hex.length); } return Uint8Array.from(hexMap.map((byte) => parseInt(byte, 16))); } @@ -57,19 +61,6 @@ export const logLevel={ debug:1, none:9, } -export class Log { - private level:number; - - constructor(level:number){ - this.level = level; - } - - public debug(m:any){ - if(this.level<=logLevel.debug){ - console.log(m); - } - } -} const units = { ptAtmm:0.35, diff --git a/tsconfig.json b/tsconfig.json index a9f1891..09bcc43 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,73 +1,12 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ - "target": "ESNEXT", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./dist", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true, /* Skip type checking of declaration files. */ - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ - }, - "include": [ - "src/**/*" - ], -} + "jsx": "react-jsx", + "lib": ["ES2015"], + "module": "CommonJS", + "target": "es6", + "esModuleInterop": true, + "resolveJsonModule": true +}, "include": [ + "src/**/*" + ], +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 1ea6c36..dca7cc1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,169 @@ # yarn lockfile v1 +"@esbuild/android-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" + integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== + +"@esbuild/android-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" + integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== + +"@esbuild/android-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" + integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== + +"@esbuild/darwin-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" + integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== + +"@esbuild/darwin-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" + integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== + +"@esbuild/freebsd-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" + integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== + +"@esbuild/freebsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" + integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== + +"@esbuild/linux-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" + integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== + +"@esbuild/linux-arm@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" + integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== + +"@esbuild/linux-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" + integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== + +"@esbuild/linux-loong64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" + integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== + +"@esbuild/linux-mips64el@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" + integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== + +"@esbuild/linux-ppc64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" + integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== + +"@esbuild/linux-riscv64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" + integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== + +"@esbuild/linux-s390x@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" + integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== + +"@esbuild/linux-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" + integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== + +"@esbuild/netbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" + integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== + +"@esbuild/openbsd-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" + integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== + +"@esbuild/sunos-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" + integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== + +"@esbuild/win32-arm64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" + integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== + +"@esbuild/win32-ia32@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" + integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== + +"@esbuild/win32-x64@0.18.20": + version "0.18.20" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d" + integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@pdf-lib/fontkit@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@pdf-lib/fontkit/-/fontkit-1.1.1.tgz#f18473892b65e3253eb73f4569785abd2c03b1e0" @@ -28,83 +191,410 @@ resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.1.1.tgz#602859584cecc91894eb23a4892f38cfa927890d" integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA== -"@types/saslprep@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/saslprep/-/saslprep-1.0.1.tgz#92720f21fd6b7807f4df4a73a1962587f60cc3d4" - integrity sha512-JHSoEmJi4Gav2Y53dIGdvW2w2tr8iymXWhI/qNiKx9/eSgREsJkn7gJK22ldVXuisQXreSyXqogtzRtT0ls8Lg== +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +bundle-require@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/bundle-require/-/bundle-require-4.0.2.tgz#65fc74ff14eabbba36d26c9a6161bd78fff6b29e" + integrity sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag== + dependencies: + load-tsconfig "^0.2.3" -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +cac@^6.7.12: + version "6.7.14" + resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" + integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== -axios@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024" - integrity sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ== +chokidar@^3.5.1: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: - delayed-stream "~1.0.0" + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" crypto-js@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== -delayed-stream@~1.0.0: +debug@^4.3.1: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +esbuild@^0.18.2: + version "0.18.20" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6" + integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== + optionalDependencies: + "@esbuild/android-arm" "0.18.20" + "@esbuild/android-arm64" "0.18.20" + "@esbuild/android-x64" "0.18.20" + "@esbuild/darwin-arm64" "0.18.20" + "@esbuild/darwin-x64" "0.18.20" + "@esbuild/freebsd-arm64" "0.18.20" + "@esbuild/freebsd-x64" "0.18.20" + "@esbuild/linux-arm" "0.18.20" + "@esbuild/linux-arm64" "0.18.20" + "@esbuild/linux-ia32" "0.18.20" + "@esbuild/linux-loong64" "0.18.20" + "@esbuild/linux-mips64el" "0.18.20" + "@esbuild/linux-ppc64" "0.18.20" + "@esbuild/linux-riscv64" "0.18.20" + "@esbuild/linux-s390x" "0.18.20" + "@esbuild/linux-x64" "0.18.20" + "@esbuild/netbsd-x64" "0.18.20" + "@esbuild/openbsd-x64" "0.18.20" + "@esbuild/sunos-x64" "0.18.20" + "@esbuild/win32-arm64" "0.18.20" + "@esbuild/win32-ia32" "0.18.20" + "@esbuild/win32-x64" "0.18.20" + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +fast-glob@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globby@^11.0.3: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +joycon@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" + integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== jsrsasign@^10.6.1: version "10.6.1" resolved "https://registry.yarnpkg.com/jsrsasign/-/jsrsasign-10.6.1.tgz#dcdfa890241f4cb72e717116f95b5ba9315bfda0" integrity sha512-emiQ05haY9CRj1Ho/LiuCqr/+8RgJuWdiHYNglIg2Qjfz0n+pnUq9I2QHplXuOMO2EnAW1oCGC1++aU5VoWSlw== -memory-pager@^1.0.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" - integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== +lilconfig@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +load-tsconfig@^0.2.3: + version "0.2.5" + resolved "https://registry.yarnpkg.com/load-tsconfig/-/load-tsconfig-0.2.5.tgz#453b8cd8961bfb912dea77eb6c168fe8cca3d3a1" + integrity sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: - mime-db "1.52.0" + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" pako@^1.0.10, pako@^1.0.11, pako@^1.0.6: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + pdf-lib@^1.17.1: version "1.17.1" resolved "https://registry.yarnpkg.com/pdf-lib/-/pdf-lib-1.17.1.tgz#9e7dd21261a0c1fb17992580885b39e7d08f451f" @@ -115,31 +605,207 @@ pdf-lib@^1.17.1: pako "^1.0.11" tslib "^1.11.1" -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +postcss-load-config@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" + integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== + dependencies: + lilconfig "^2.0.5" + yaml "^2.1.1" + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rollup@^3.2.5: + version "3.29.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" + integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== + optionalDependencies: + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map@0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -saslprep@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" - integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag== +sucrase@^3.20.3: + version "3.34.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f" + integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw== dependencies: - sparse-bitfield "^3.0.3" + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" -sparse-bitfield@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" - integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ== +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== dependencies: - memory-pager "^1.0.2" + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== + dependencies: + punycode "^2.1.0" + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== tslib@^1.11.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tsup@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/tsup/-/tsup-7.2.0.tgz#bb24c0d5e436477900c712e42adc67200607303c" + integrity sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ== + dependencies: + bundle-require "^4.0.0" + cac "^6.7.12" + chokidar "^3.5.1" + debug "^4.3.1" + esbuild "^0.18.2" + execa "^5.0.0" + globby "^11.0.3" + joycon "^3.0.1" + postcss-load-config "^4.0.1" + resolve-from "^5.0.0" + rollup "^3.2.5" + source-map "0.8.0-beta.0" + sucrase "^3.20.3" + tree-kill "^1.2.2" + typescript@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yaml@^2.1.1: + version "2.3.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.3.tgz#01f6d18ef036446340007db8e016810e5d64aad9" + integrity sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==