pdf-lite 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EXAMPLES.md +51 -70
- package/README.md +1 -1
- package/dist/acroform/appearance/index.d.ts +4 -4
- package/dist/acroform/appearance/index.js +4 -4
- package/dist/acroform/appearance/{PdfAppearanceStream.d.ts → pdf-appearance-stream.d.ts} +9 -3
- package/dist/acroform/appearance/{PdfAppearanceStream.js → pdf-appearance-stream.js} +14 -5
- package/dist/acroform/appearance/{PdfButtonAppearanceStream.d.ts → pdf-button-appearance-stream.d.ts} +3 -2
- package/dist/acroform/appearance/pdf-button-appearance-stream.js +58 -0
- package/dist/acroform/appearance/pdf-choice-appearance-stream.d.ts +22 -0
- package/dist/acroform/appearance/pdf-choice-appearance-stream.js +75 -0
- package/dist/acroform/appearance/pdf-graphics.d.ts +51 -0
- package/dist/acroform/appearance/pdf-graphics.js +239 -0
- package/dist/acroform/appearance/{PdfTextAppearanceStream.d.ts → pdf-text-appearance-stream.d.ts} +7 -2
- package/dist/acroform/appearance/pdf-text-appearance-stream.js +104 -0
- package/dist/acroform/fields/index.d.ts +7 -7
- package/dist/acroform/fields/index.js +7 -7
- package/dist/acroform/fields/pdf-button-form-field.d.ts +14 -0
- package/dist/acroform/fields/pdf-button-form-field.js +70 -0
- package/dist/acroform/fields/pdf-choice-form-field.d.ts +19 -0
- package/dist/acroform/fields/pdf-choice-form-field.js +112 -0
- package/dist/acroform/fields/{PdfFormFieldFlags.d.ts → pdf-form-field-flags.d.ts} +5 -6
- package/dist/acroform/fields/{PdfFormFieldFlags.js → pdf-form-field-flags.js} +12 -18
- package/dist/acroform/fields/{PdfFormField.d.ts → pdf-form-field.d.ts} +37 -38
- package/dist/acroform/fields/pdf-form-field.js +519 -0
- package/dist/acroform/fields/{PdfSignatureFormField.d.ts → pdf-signature-form-field.d.ts} +1 -1
- package/dist/acroform/fields/{PdfSignatureFormField.js → pdf-signature-form-field.js} +1 -1
- package/dist/acroform/fields/{PdfTextFormField.d.ts → pdf-text-form-field.d.ts} +1 -1
- package/dist/acroform/fields/{PdfTextFormField.js → pdf-text-form-field.js} +11 -13
- package/dist/acroform/fields/types.d.ts +6 -1
- package/dist/acroform/index.d.ts +1 -3
- package/dist/acroform/index.js +1 -3
- package/dist/acroform/pdf-acro-form.d.ts +45 -0
- package/dist/acroform/pdf-acro-form.js +203 -0
- package/dist/acroform/xfa/index.d.ts +3 -3
- package/dist/acroform/xfa/index.js +2 -2
- package/dist/acroform/xfa/{PdfXfaData.d.ts → pdf-xfa-data.d.ts} +4 -3
- package/dist/acroform/xfa/{PdfXfaData.js → pdf-xfa-data.js} +16 -12
- package/dist/acroform/xfa/pdf-xfa-form.d.ts +16 -0
- package/dist/acroform/xfa/pdf-xfa-form.js +34 -0
- package/dist/annotations/index.d.ts +3 -4
- package/dist/annotations/index.js +3 -4
- package/dist/annotations/{PdfAnnotationFlags.d.ts → pdf-annotation-flags.d.ts} +3 -4
- package/dist/annotations/{PdfAnnotationFlags.js → pdf-annotation-flags.js} +5 -6
- package/dist/annotations/{PdfAnnotation.d.ts → pdf-annotation.d.ts} +31 -5
- package/dist/annotations/{PdfAnnotation.js → pdf-annotation.js} +31 -19
- package/dist/annotations/pdf-default-resources.d.ts +11 -0
- package/dist/annotations/pdf-default-resources.js +3 -0
- package/dist/annotations/{PdfWidgetAnnotation.d.ts → pdf-widget-annotation.d.ts} +1 -1
- package/dist/annotations/{PdfWidgetAnnotation.js → pdf-widget-annotation.js} +1 -1
- package/dist/core/decoder.js +1 -1
- package/dist/core/objects/pdf-array.d.ts +8 -1
- package/dist/core/objects/pdf-array.js +31 -0
- package/dist/core/objects/pdf-dictionary.d.ts +2 -0
- package/dist/core/objects/pdf-dictionary.js +14 -7
- package/dist/core/objects/pdf-hexadecimal.d.ts +1 -0
- package/dist/core/objects/pdf-hexadecimal.js +3 -3
- package/dist/core/objects/pdf-indirect-object.d.ts +18 -9
- package/dist/core/objects/pdf-indirect-object.js +75 -16
- package/dist/core/objects/pdf-number.d.ts +1 -0
- package/dist/core/objects/pdf-number.js +5 -4
- package/dist/core/objects/pdf-object-reference.d.ts +8 -1
- package/dist/core/objects/pdf-object-reference.js +14 -0
- package/dist/core/objects/pdf-object.d.ts +14 -0
- package/dist/core/objects/pdf-object.js +36 -0
- package/dist/core/objects/pdf-start-xref.d.ts +1 -0
- package/dist/core/objects/pdf-start-xref.js +4 -0
- package/dist/core/objects/pdf-stream.d.ts +44 -7
- package/dist/core/objects/pdf-stream.js +284 -26
- package/dist/core/objects/pdf-string.d.ts +1 -0
- package/dist/core/objects/pdf-string.js +3 -6
- package/dist/core/objects/pdf-trailer.d.ts +1 -0
- package/dist/core/objects/pdf-trailer.js +6 -3
- package/dist/core/objects/pdf-xref-table.js +1 -1
- package/dist/core/parser/incremental-parser.d.ts +0 -13
- package/dist/core/parser/incremental-parser.js +1 -18
- package/dist/core/ref.d.ts +3 -1
- package/dist/core/ref.js +8 -5
- package/dist/core/streams/object-stream.d.ts +1 -1
- package/dist/core/streams/object-stream.js +1 -1
- package/dist/core/tokens/token.d.ts +2 -1
- package/dist/core/tokens/token.js +3 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.js +24 -0
- package/dist/fonts/index.d.ts +0 -1
- package/dist/fonts/index.js +0 -1
- package/dist/fonts/pdf-font.d.ts +94 -32
- package/dist/fonts/pdf-font.js +301 -83
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/pdf/index.d.ts +2 -1
- package/dist/pdf/index.js +2 -1
- package/dist/pdf/pdf-document.d.ts +61 -36
- package/dist/pdf/pdf-document.js +315 -117
- package/dist/pdf/pdf-page.d.ts +50 -0
- package/dist/pdf/pdf-page.js +144 -0
- package/dist/pdf/pdf-pages.d.ts +28 -0
- package/dist/pdf/pdf-pages.js +94 -0
- package/dist/pdf/pdf-reader.d.ts +5 -1
- package/dist/pdf/pdf-reader.js +36 -2
- package/dist/pdf/pdf-revision.d.ts +3 -3
- package/dist/pdf/pdf-revision.js +7 -7
- package/dist/pdf/pdf-xref-lookup.js +34 -14
- package/dist/signing/document-security-store.d.ts +14 -17
- package/dist/signing/document-security-store.js +19 -34
- package/dist/signing/signer.d.ts +23 -8
- package/dist/signing/signer.js +51 -17
- package/dist/utils/encodePdfText.d.ts +17 -0
- package/dist/utils/encodePdfText.js +61 -0
- package/dist/utils/index.d.ts +1 -2
- package/dist/utils/index.js +1 -2
- package/dist/utils/needsCentralWhitespace.d.ts +10 -0
- package/dist/utils/needsCentralWhitespace.js +34 -0
- package/package.json +3 -3
- package/dist/acroform/PdfAcroForm.d.ts +0 -63
- package/dist/acroform/PdfAcroForm.js +0 -279
- package/dist/acroform/PdfFontEncodingCache.d.ts +0 -16
- package/dist/acroform/PdfFontEncodingCache.js +0 -75
- package/dist/acroform/acroform.d.ts +0 -9
- package/dist/acroform/acroform.js +0 -7
- package/dist/acroform/appearance/PdfButtonAppearanceStream.js +0 -54
- package/dist/acroform/appearance/PdfChoiceAppearanceStream.d.ts +0 -15
- package/dist/acroform/appearance/PdfChoiceAppearanceStream.js +0 -48
- package/dist/acroform/appearance/PdfTextAppearanceStream.js +0 -75
- package/dist/acroform/fields/PdfButtonFormField.d.ts +0 -9
- package/dist/acroform/fields/PdfButtonFormField.js +0 -35
- package/dist/acroform/fields/PdfChoiceFormField.d.ts +0 -9
- package/dist/acroform/fields/PdfChoiceFormField.js +0 -46
- package/dist/acroform/fields/PdfFormField.js +0 -499
- package/dist/acroform/manager.d.ts +0 -33
- package/dist/acroform/manager.js +0 -51
- package/dist/acroform/xfa/PdfXfaForm.d.ts +0 -12
- package/dist/acroform/xfa/PdfXfaForm.js +0 -64
- package/dist/annotations/PdfAnnotationWriter.d.ts +0 -20
- package/dist/annotations/PdfAnnotationWriter.js +0 -76
- package/dist/fonts/font-manager.d.ts +0 -127
- package/dist/fonts/font-manager.js +0 -378
- package/dist/pdf/errors.d.ts +0 -6
- package/dist/pdf/errors.js +0 -6
- package/dist/utils/predictors.d.ts +0 -113
- package/dist/utils/predictors.js +0 -279
- /package/dist/acroform/fields/{PdfDefaultAppearance.d.ts → pdf-default-appearance.d.ts} +0 -0
- /package/dist/acroform/fields/{PdfDefaultAppearance.js → pdf-default-appearance.js} +0 -0
- /package/dist/utils/{IterableReadableStream.d.ts → iterable-readable-stream.d.ts} +0 -0
- /package/dist/utils/{IterableReadableStream.js → iterable-readable-stream.js} +0 -0
|
@@ -30,23 +30,20 @@ export class PdfDocumentSecurityStoreDictionary extends PdfDictionary {
|
|
|
30
30
|
* @example
|
|
31
31
|
* ```typescript
|
|
32
32
|
* const dss = new PdfDocumentSecurityStoreObject(document)
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
33
|
+
* dss.addCert(certificateBytes)
|
|
34
|
+
* dss.addCrl(crlBytes)
|
|
35
|
+
* dss.addOcsp(ocspBytes)
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
export class PdfDocumentSecurityStoreObject extends PdfIndirectObject {
|
|
39
|
-
/** Reference to the parent document. */
|
|
40
|
-
document;
|
|
41
39
|
/**
|
|
42
40
|
* Creates a new DSS object.
|
|
43
41
|
*
|
|
44
42
|
* @param document - The parent PDF document.
|
|
45
43
|
* @param content - Optional pre-existing DSS dictionary.
|
|
46
44
|
*/
|
|
47
|
-
constructor(
|
|
45
|
+
constructor(content) {
|
|
48
46
|
super(content ?? new PdfDocumentSecurityStoreDictionary());
|
|
49
|
-
this.document = document;
|
|
50
47
|
}
|
|
51
48
|
/**
|
|
52
49
|
* Adds an OCSP response to the DSS, avoiding duplicates.
|
|
@@ -54,25 +51,21 @@ export class PdfDocumentSecurityStoreObject extends PdfIndirectObject {
|
|
|
54
51
|
* @param ocsp - The DER-encoded OCSP response.
|
|
55
52
|
* @returns The created or existing OCSP object.
|
|
56
53
|
*/
|
|
57
|
-
|
|
54
|
+
addOcsp(ocsp) {
|
|
58
55
|
const newOcsp = new PdfStream(ocsp);
|
|
59
56
|
let ocspArray = this.content.get('OCSPs');
|
|
60
|
-
const currentOcsps = (
|
|
61
|
-
const obj = await this.document.readObject(ref);
|
|
62
|
-
return obj;
|
|
63
|
-
})));
|
|
57
|
+
const currentOcsps = (ocspArray?.items ?? []).map((ref) => ref.resolve());
|
|
64
58
|
for (const existingOcsp of currentOcsps) {
|
|
65
59
|
if (existingOcsp.content.equals(newOcsp)) {
|
|
66
|
-
return existingOcsp;
|
|
60
|
+
return existingOcsp.becomes(PdfOcspObject);
|
|
67
61
|
}
|
|
68
62
|
}
|
|
69
63
|
const ocspObject = new PdfOcspObject(newOcsp);
|
|
70
|
-
this.document.add(ocspObject);
|
|
71
64
|
if (!ocspArray) {
|
|
72
65
|
ocspArray = new PdfArray([]);
|
|
73
66
|
this.content.set('OCSPs', ocspArray);
|
|
74
67
|
}
|
|
75
|
-
ocspArray.
|
|
68
|
+
ocspArray.push(ocspObject.reference);
|
|
76
69
|
return ocspObject;
|
|
77
70
|
}
|
|
78
71
|
/**
|
|
@@ -81,24 +74,20 @@ export class PdfDocumentSecurityStoreObject extends PdfIndirectObject {
|
|
|
81
74
|
* @param crl - The DER-encoded CRL.
|
|
82
75
|
* @returns The created or existing CRL object.
|
|
83
76
|
*/
|
|
84
|
-
|
|
77
|
+
addCrl(crl) {
|
|
85
78
|
let crlArray = this.content.get('CRLs');
|
|
86
|
-
const currentCrls = (
|
|
87
|
-
const obj = await this.document.readObject(ref);
|
|
88
|
-
return obj;
|
|
89
|
-
})));
|
|
79
|
+
const currentCrls = (crlArray?.items ?? []).map((ref) => ref.resolve());
|
|
90
80
|
for (const existingCrl of currentCrls) {
|
|
91
81
|
if (existingCrl.content.equals(new PdfStream(crl))) {
|
|
92
|
-
return existingCrl;
|
|
82
|
+
return existingCrl.becomes(PdfCrlObject);
|
|
93
83
|
}
|
|
94
84
|
}
|
|
95
85
|
const crlObject = new PdfCrlObject(new PdfStream(crl));
|
|
96
|
-
this.document.add(crlObject);
|
|
97
86
|
if (!crlArray) {
|
|
98
87
|
crlArray = new PdfArray([]);
|
|
99
88
|
this.content.set('CRLs', crlArray);
|
|
100
89
|
}
|
|
101
|
-
crlArray.
|
|
90
|
+
crlArray.push(crlObject.reference);
|
|
102
91
|
return crlObject;
|
|
103
92
|
}
|
|
104
93
|
/**
|
|
@@ -107,24 +96,20 @@ export class PdfDocumentSecurityStoreObject extends PdfIndirectObject {
|
|
|
107
96
|
* @param cert - The DER-encoded certificate.
|
|
108
97
|
* @returns The created or existing certificate object.
|
|
109
98
|
*/
|
|
110
|
-
|
|
99
|
+
addCert(cert) {
|
|
111
100
|
let certArray = this.content.get('Certs');
|
|
112
|
-
const currentCerts = (
|
|
113
|
-
const obj = await this.document.readObject(ref);
|
|
114
|
-
return obj;
|
|
115
|
-
})));
|
|
101
|
+
const currentCerts = (certArray?.items ?? []).map((ref) => ref.resolve());
|
|
116
102
|
for (const existingCert of currentCerts) {
|
|
117
103
|
if (existingCert.content.equals(new PdfStream(cert))) {
|
|
118
|
-
return existingCert;
|
|
104
|
+
return existingCert.becomes(PdfCertObject);
|
|
119
105
|
}
|
|
120
106
|
}
|
|
121
107
|
const certObject = new PdfCertObject(new PdfStream(cert));
|
|
122
|
-
this.document.add(certObject);
|
|
123
108
|
if (!certArray) {
|
|
124
109
|
certArray = new PdfArray([]);
|
|
125
110
|
this.content.set('Certs', certArray);
|
|
126
111
|
}
|
|
127
|
-
certArray.
|
|
112
|
+
certArray.push(certObject.reference);
|
|
128
113
|
return certObject;
|
|
129
114
|
}
|
|
130
115
|
/**
|
|
@@ -132,12 +117,12 @@ export class PdfDocumentSecurityStoreObject extends PdfIndirectObject {
|
|
|
132
117
|
*
|
|
133
118
|
* @param revocationInfo - The revocation information to add.
|
|
134
119
|
*/
|
|
135
|
-
|
|
120
|
+
addRevocationInfo(revocationInfo) {
|
|
136
121
|
for (const ocsp of revocationInfo.ocsps ?? []) {
|
|
137
|
-
|
|
122
|
+
this.addOcsp(ocsp);
|
|
138
123
|
}
|
|
139
124
|
for (const crl of revocationInfo.crls ?? []) {
|
|
140
|
-
|
|
125
|
+
this.addCrl(crl);
|
|
141
126
|
}
|
|
142
127
|
}
|
|
143
128
|
/**
|
package/dist/signing/signer.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PdfDocumentSecurityStoreObject } from './document-security-store.js';
|
|
2
2
|
import { PdfSignatureObject } from './signatures/index.js';
|
|
3
3
|
import { PdfSignatureVerificationResult, CertificateValidationOptions, PdfSignatureSubType } from './types.js';
|
|
4
|
+
import { PdfDocument } from '../pdf/pdf-document.js';
|
|
4
5
|
/**
|
|
5
|
-
* Result of verifying all signatures in a document.
|
|
6
|
+
* Result of verifying all signatures in a this.document.
|
|
6
7
|
*/
|
|
7
8
|
export type PdfDocumentVerificationResult = {
|
|
8
9
|
/** Whether all signatures in the document are valid. */
|
|
@@ -11,7 +12,7 @@ export type PdfDocumentVerificationResult = {
|
|
|
11
12
|
signatures: {
|
|
12
13
|
/** The signature subfilter type. */
|
|
13
14
|
type: PdfSignatureSubType;
|
|
14
|
-
/** Index of the signature in the document. */
|
|
15
|
+
/** Index of the signature in the this.document. */
|
|
15
16
|
index: number;
|
|
16
17
|
/** The signature object. */
|
|
17
18
|
signature: PdfSignatureObject;
|
|
@@ -30,16 +31,22 @@ export type PdfDocumentVerificationResult = {
|
|
|
30
31
|
* ```
|
|
31
32
|
*/
|
|
32
33
|
export declare class PdfSigner {
|
|
34
|
+
/** The PDF document to be signed. */
|
|
35
|
+
document: PdfDocument;
|
|
33
36
|
/** Whether to use the Document Security Store for revocation information. */
|
|
34
37
|
useDocumentSecurityStore: boolean;
|
|
38
|
+
constructor(options: {
|
|
39
|
+
useDocumentSecurityStore?: boolean;
|
|
40
|
+
document: PdfDocument;
|
|
41
|
+
});
|
|
35
42
|
/**
|
|
36
|
-
* Signs all signature objects in the document.
|
|
43
|
+
* Signs all signature objects in the this.document.
|
|
37
44
|
* Computes byte ranges, generates signatures, and optionally adds revocation info to DSS.
|
|
38
45
|
*
|
|
39
46
|
* @param document - The PDF document to sign.
|
|
40
|
-
* @returns The signed document.
|
|
47
|
+
* @returns The signed this.document.
|
|
41
48
|
*/
|
|
42
|
-
sign(
|
|
49
|
+
sign(): Promise<void>;
|
|
43
50
|
/**
|
|
44
51
|
* Instantiates the appropriate signature object based on SubFilter type.
|
|
45
52
|
*
|
|
@@ -48,7 +55,7 @@ export declare class PdfSigner {
|
|
|
48
55
|
*/
|
|
49
56
|
private instantiateSignatureObject;
|
|
50
57
|
/**
|
|
51
|
-
* Verifies all signatures in the document.
|
|
58
|
+
* Verifies all signatures in the this.document.
|
|
52
59
|
* First serializes the document to bytes and reloads it to ensure signatures
|
|
53
60
|
* are properly deserialized into the correct classes before verification.
|
|
54
61
|
* Then searches for signature objects, computes their byte ranges, and verifies each one.
|
|
@@ -72,7 +79,15 @@ export declare class PdfSigner {
|
|
|
72
79
|
* }
|
|
73
80
|
* ```
|
|
74
81
|
*/
|
|
75
|
-
verify(
|
|
82
|
+
verify(options?: {
|
|
76
83
|
certificateValidation?: CertificateValidationOptions | boolean;
|
|
77
84
|
}): Promise<PdfDocumentVerificationResult>;
|
|
85
|
+
/**
|
|
86
|
+
* Sets the Document Security Store (DSS) for the this.document.
|
|
87
|
+
* Used for long-term validation of digital signatures.
|
|
88
|
+
*
|
|
89
|
+
* @param dss - The Document Security Store object to set
|
|
90
|
+
* @throws Error if the document has no root dictionary
|
|
91
|
+
*/
|
|
92
|
+
setDocumentSecurityStore(dss: PdfDocumentSecurityStoreObject): void;
|
|
78
93
|
}
|
package/dist/signing/signer.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { PdfCommentToken } from '../core/tokens/comment-token.js';
|
|
2
|
-
import { PdfHexadecimalToken } from '../core/tokens/hexadecimal-token.js';
|
|
3
|
-
import { PdfNameToken } from '../core/tokens/name-token.js';
|
|
4
1
|
import { concatUint8Arrays } from '../utils/concatUint8Arrays.js';
|
|
5
2
|
import { PdfDocumentSecurityStoreObject } from './document-security-store.js';
|
|
6
3
|
import { PdfSignatureObject, PdfAdbePkcs7DetachedSignatureObject, PdfAdbePkcs7Sha1SignatureObject, PdfAdbePkcsX509RsaSha1SignatureObject, PdfEtsiCadesDetachedSignatureObject, PdfEtsiRfc3161SignatureObject, PdfSignatureDictionary, } from './signatures/index.js';
|
|
@@ -8,6 +5,9 @@ import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
|
8
5
|
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
9
6
|
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
10
7
|
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
8
|
+
import { PdfNameToken } from '../core/tokens/name-token.js';
|
|
9
|
+
import { PdfCommentToken } from '../core/tokens/comment-token.js';
|
|
10
|
+
import { PdfHexadecimalToken } from '../core/tokens/hexadecimal-token.js';
|
|
11
11
|
/**
|
|
12
12
|
* Handles digital signing operations for PDF documents.
|
|
13
13
|
* Processes signature objects and optionally stores revocation information in the DSS.
|
|
@@ -19,25 +19,39 @@ import { PdfArray } from '../core/objects/pdf-array.js';
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
export class PdfSigner {
|
|
22
|
+
/** The PDF document to be signed. */
|
|
23
|
+
document;
|
|
22
24
|
/** Whether to use the Document Security Store for revocation information. */
|
|
23
25
|
useDocumentSecurityStore = true;
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.document = options.document;
|
|
28
|
+
if (options?.useDocumentSecurityStore !== undefined) {
|
|
29
|
+
this.useDocumentSecurityStore = options.useDocumentSecurityStore;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
24
32
|
/**
|
|
25
|
-
* Signs all signature objects in the document.
|
|
33
|
+
* Signs all signature objects in the this.document.
|
|
26
34
|
* Computes byte ranges, generates signatures, and optionally adds revocation info to DSS.
|
|
27
35
|
*
|
|
28
36
|
* @param document - The PDF document to sign.
|
|
29
|
-
* @returns The signed document.
|
|
37
|
+
* @returns The signed this.document.
|
|
30
38
|
*/
|
|
31
|
-
async sign(
|
|
39
|
+
async sign() {
|
|
32
40
|
const signatures = [
|
|
33
|
-
...document.objects.filter((x) => x instanceof PdfSignatureObject),
|
|
41
|
+
...this.document.objects.filter((x) => x instanceof PdfSignatureObject),
|
|
34
42
|
];
|
|
43
|
+
// Move all signature objects to the end of the document in a new revision to ensure their byte positions are after all other content.
|
|
44
|
+
signatures.forEach((sig) => {
|
|
45
|
+
this.document.deleteObject(sig);
|
|
46
|
+
this.document.startNewRevision();
|
|
47
|
+
this.document.add(sig);
|
|
48
|
+
});
|
|
35
49
|
const dss = this.useDocumentSecurityStore
|
|
36
|
-
? (document.objects.find((x) => x instanceof PdfDocumentSecurityStoreObject) ?? new PdfDocumentSecurityStoreObject(
|
|
50
|
+
? (this.document.objects.find((x) => x instanceof PdfDocumentSecurityStoreObject) ?? new PdfDocumentSecurityStoreObject())
|
|
37
51
|
: undefined;
|
|
38
52
|
for (let i = 0; i < signatures.length; i++) {
|
|
39
53
|
const signature = signatures[i];
|
|
40
|
-
const tokens = document.tokensWithObjects();
|
|
54
|
+
const tokens = this.document.tokensWithObjects();
|
|
41
55
|
const signableTokens = [];
|
|
42
56
|
let contentsOffset = 0;
|
|
43
57
|
let contentsLength = 0;
|
|
@@ -77,7 +91,7 @@ export class PdfSigner {
|
|
|
77
91
|
byteCount - (contentsOffset + contentsLength),
|
|
78
92
|
];
|
|
79
93
|
signature.setByteRange(byteRange);
|
|
80
|
-
const allBytes = document.toBytes();
|
|
94
|
+
const allBytes = this.document.toBytes();
|
|
81
95
|
const toSign = concatUint8Arrays(allBytes.slice(byteRange[0], byteRange[1]), allBytes.slice(byteRange[2], byteRange[3] + byteRange[2]));
|
|
82
96
|
const { signedBytes, revocationInfo } = await signature.sign({
|
|
83
97
|
bytes: toSign,
|
|
@@ -85,13 +99,12 @@ export class PdfSigner {
|
|
|
85
99
|
});
|
|
86
100
|
signature.setSignedBytes(signedBytes);
|
|
87
101
|
if (dss && revocationInfo) {
|
|
88
|
-
|
|
102
|
+
dss.addRevocationInfo(revocationInfo);
|
|
89
103
|
}
|
|
90
104
|
}
|
|
91
105
|
if (dss && !dss.isEmpty()) {
|
|
92
|
-
|
|
106
|
+
this.setDocumentSecurityStore(dss);
|
|
93
107
|
}
|
|
94
|
-
return document;
|
|
95
108
|
}
|
|
96
109
|
/**
|
|
97
110
|
* Instantiates the appropriate signature object based on SubFilter type.
|
|
@@ -161,7 +174,7 @@ export class PdfSigner {
|
|
|
161
174
|
return signatureObj;
|
|
162
175
|
}
|
|
163
176
|
/**
|
|
164
|
-
* Verifies all signatures in the document.
|
|
177
|
+
* Verifies all signatures in the this.document.
|
|
165
178
|
* First serializes the document to bytes and reloads it to ensure signatures
|
|
166
179
|
* are properly deserialized into the correct classes before verification.
|
|
167
180
|
* Then searches for signature objects, computes their byte ranges, and verifies each one.
|
|
@@ -185,11 +198,11 @@ export class PdfSigner {
|
|
|
185
198
|
* }
|
|
186
199
|
* ```
|
|
187
200
|
*/
|
|
188
|
-
async verify(
|
|
189
|
-
const documentBytes = document.toBytes();
|
|
201
|
+
async verify(options) {
|
|
202
|
+
const documentBytes = this.document.toBytes();
|
|
190
203
|
const results = [];
|
|
191
204
|
let allValid = true;
|
|
192
|
-
const documentObjects = document.objects;
|
|
205
|
+
const documentObjects = this.document.objects;
|
|
193
206
|
for (let i = 0; i < documentObjects.length; i++) {
|
|
194
207
|
const obj = documentObjects[i];
|
|
195
208
|
if (!(obj instanceof PdfIndirectObject)) {
|
|
@@ -284,4 +297,25 @@ export class PdfSigner {
|
|
|
284
297
|
signatures: results,
|
|
285
298
|
};
|
|
286
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Sets the Document Security Store (DSS) for the this.document.
|
|
302
|
+
* Used for long-term validation of digital signatures.
|
|
303
|
+
*
|
|
304
|
+
* @param dss - The Document Security Store object to set
|
|
305
|
+
* @throws Error if the document has no root dictionary
|
|
306
|
+
*/
|
|
307
|
+
setDocumentSecurityStore(dss) {
|
|
308
|
+
const root = this.document.root;
|
|
309
|
+
if (!root?.content) {
|
|
310
|
+
throw new Error('Cannot set DSS - document has no root dictionary');
|
|
311
|
+
}
|
|
312
|
+
// Add DSS in a new incremental revision so it doesn't change
|
|
313
|
+
// byte positions in earlier revisions (which have signed ByteRanges).
|
|
314
|
+
this.document.startNewRevision();
|
|
315
|
+
// Clone the root catalog into the new revision with the DSS reference
|
|
316
|
+
const updatedRoot = root.clone();
|
|
317
|
+
updatedRoot.content.set('DSS', dss.reference);
|
|
318
|
+
this.document.add(updatedRoot);
|
|
319
|
+
this.document.add(dss);
|
|
320
|
+
}
|
|
287
321
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encodes a text string for use in a PDF content stream text operator (`Tj`).
|
|
3
|
+
*
|
|
4
|
+
* PDF literal strings `(...)` in content streams are raw bytes interpreted by the
|
|
5
|
+
* font's encoding — NOT UTF-8. This function produces the correct PDF string token:
|
|
6
|
+
*
|
|
7
|
+
* - Type0/Identity-H fonts: hex string `<XXXX...>` with 2 bytes per character (CID = Unicode codepoint)
|
|
8
|
+
* - Single-byte fonts: PDF literal `(...)` with octal escapes `\ooo` for byte values ≥ 0x80,
|
|
9
|
+
* using the reverse encoding map when available for characters outside the Latin-1 range.
|
|
10
|
+
*
|
|
11
|
+
* @param text - The Unicode text to encode
|
|
12
|
+
* @param isUnicode - True if the font uses Type0/Identity-H encoding (2-byte CID per character)
|
|
13
|
+
* @param reverseEncodingMap - Optional map from Unicode character to byte code,
|
|
14
|
+
* derived by inverting the font's Differences-based encoding map
|
|
15
|
+
* @returns A PDF string token ready to use before `Tj`, e.g. `<0050> Tj` or `(text) Tj`
|
|
16
|
+
*/
|
|
17
|
+
export declare function encodePdfText(text: string, isUnicode: boolean, reverseEncodingMap?: Map<string, number>): string;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encodes a text string for use in a PDF content stream text operator (`Tj`).
|
|
3
|
+
*
|
|
4
|
+
* PDF literal strings `(...)` in content streams are raw bytes interpreted by the
|
|
5
|
+
* font's encoding — NOT UTF-8. This function produces the correct PDF string token:
|
|
6
|
+
*
|
|
7
|
+
* - Type0/Identity-H fonts: hex string `<XXXX...>` with 2 bytes per character (CID = Unicode codepoint)
|
|
8
|
+
* - Single-byte fonts: PDF literal `(...)` with octal escapes `\ooo` for byte values ≥ 0x80,
|
|
9
|
+
* using the reverse encoding map when available for characters outside the Latin-1 range.
|
|
10
|
+
*
|
|
11
|
+
* @param text - The Unicode text to encode
|
|
12
|
+
* @param isUnicode - True if the font uses Type0/Identity-H encoding (2-byte CID per character)
|
|
13
|
+
* @param reverseEncodingMap - Optional map from Unicode character to byte code,
|
|
14
|
+
* derived by inverting the font's Differences-based encoding map
|
|
15
|
+
* @returns A PDF string token ready to use before `Tj`, e.g. `<0050> Tj` or `(text) Tj`
|
|
16
|
+
*/
|
|
17
|
+
export function encodePdfText(text, isUnicode, reverseEncodingMap) {
|
|
18
|
+
if (isUnicode) {
|
|
19
|
+
// Type0 / Identity-H: 2-byte big-endian CID per code point
|
|
20
|
+
let hex = '<';
|
|
21
|
+
for (const char of text) {
|
|
22
|
+
const code = char.codePointAt(0) ?? 0;
|
|
23
|
+
hex += code.toString(16).padStart(4, '0');
|
|
24
|
+
}
|
|
25
|
+
return hex + '>';
|
|
26
|
+
}
|
|
27
|
+
// Single-byte font: PDF literal string with octal escapes for non-ASCII bytes
|
|
28
|
+
let result = '(';
|
|
29
|
+
for (const char of text) {
|
|
30
|
+
const code = char.charCodeAt(0);
|
|
31
|
+
if (code === 0x28) {
|
|
32
|
+
result += '\\('; // (
|
|
33
|
+
}
|
|
34
|
+
else if (code === 0x29) {
|
|
35
|
+
result += '\\)'; // )
|
|
36
|
+
}
|
|
37
|
+
else if (code === 0x5c) {
|
|
38
|
+
result += '\\\\'; // \
|
|
39
|
+
}
|
|
40
|
+
else if (code === 0x0a) {
|
|
41
|
+
result += '\\n';
|
|
42
|
+
}
|
|
43
|
+
else if (code === 0x0d) {
|
|
44
|
+
result += '\\r';
|
|
45
|
+
}
|
|
46
|
+
else if (code < 0x80) {
|
|
47
|
+
result += char; // ASCII: safe to write directly
|
|
48
|
+
}
|
|
49
|
+
else if (reverseEncodingMap?.has(char)) {
|
|
50
|
+
// Custom font encoding (Differences): use the mapped byte code
|
|
51
|
+
const byteCode = reverseEncodingMap.get(char);
|
|
52
|
+
result += '\\' + byteCode.toString(8).padStart(3, '0');
|
|
53
|
+
}
|
|
54
|
+
else if (code <= 0xff) {
|
|
55
|
+
// Latin-1 range: encode as octal so UTF-8 serialisation doesn't mangle it
|
|
56
|
+
result += '\\' + code.toString(8).padStart(3, '0');
|
|
57
|
+
}
|
|
58
|
+
// Characters above 0xFF with no mapping are silently dropped
|
|
59
|
+
}
|
|
60
|
+
return result + ')';
|
|
61
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './iterable-readable-stream.js';
|
|
2
2
|
export * from './algos.js';
|
|
3
3
|
export * from './assert.js';
|
|
4
4
|
export * from './bytesToHex.js';
|
|
@@ -13,7 +13,6 @@ export * from './hexBytesToString.js';
|
|
|
13
13
|
export * from './hexToBytes.js';
|
|
14
14
|
export * from './needsUnicodeEncoding.js';
|
|
15
15
|
export * from './padBytes.js';
|
|
16
|
-
export * from './predictors.js';
|
|
17
16
|
export * from './replaceInBuffer.js';
|
|
18
17
|
export * from './stringToBytes.js';
|
|
19
18
|
export * from './stringToHexBytes.js';
|
package/dist/utils/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './iterable-readable-stream.js';
|
|
2
2
|
export * from './algos.js';
|
|
3
3
|
export * from './assert.js';
|
|
4
4
|
export * from './bytesToHex.js';
|
|
@@ -13,7 +13,6 @@ export * from './hexBytesToString.js';
|
|
|
13
13
|
export * from './hexToBytes.js';
|
|
14
14
|
export * from './needsUnicodeEncoding.js';
|
|
15
15
|
export * from './padBytes.js';
|
|
16
|
-
export * from './predictors.js';
|
|
17
16
|
export * from './replaceInBuffer.js';
|
|
18
17
|
export * from './stringToBytes.js';
|
|
19
18
|
export * from './stringToHexBytes.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PdfObject } from '../core/objects/pdf-object.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if the given PDF object's serialized form starts with a
|
|
4
|
+
* non-delimiter character, meaning it requires whitespace separation from
|
|
5
|
+
* a preceding token to avoid ambiguous parsing.
|
|
6
|
+
*
|
|
7
|
+
* Self-delimiting types (PdfString, PdfHexadecimal, PdfArray, PdfDictionary)
|
|
8
|
+
* start with `(`, `<`, `[`, or `<<` and do not need a leading space.
|
|
9
|
+
*/
|
|
10
|
+
export declare function needsCentralWhitespace(obj1?: PdfObject, obj2?: PdfObject): boolean;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PdfBoolean } from '../core/objects/pdf-boolean.js';
|
|
2
|
+
import { PdfNull } from '../core/objects/pdf-null.js';
|
|
3
|
+
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
4
|
+
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
5
|
+
/**
|
|
6
|
+
* Returns true if the given PDF object's serialized form starts with a
|
|
7
|
+
* non-delimiter character, meaning it requires whitespace separation from
|
|
8
|
+
* a preceding token to avoid ambiguous parsing.
|
|
9
|
+
*
|
|
10
|
+
* Self-delimiting types (PdfString, PdfHexadecimal, PdfArray, PdfDictionary)
|
|
11
|
+
* start with `(`, `<`, `[`, or `<<` and do not need a leading space.
|
|
12
|
+
*/
|
|
13
|
+
export function needsCentralWhitespace(obj1, obj2) {
|
|
14
|
+
if (!obj1 || !obj2) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
if (obj1.postTokens === undefined && obj2.preTokens === undefined) {
|
|
18
|
+
// Undefined means tokens will be generated
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (obj1.isTrailingDelimited) {
|
|
22
|
+
// Self-delimiting types (string, hex, array, dict) end with a delimiter
|
|
23
|
+
// character and never require trailing whitespace before the next token
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const tokens = [...(obj1.postTokens ?? []), ...(obj2?.preTokens ?? [])];
|
|
27
|
+
if (tokens.length > 0) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return (obj2 instanceof PdfObjectReference ||
|
|
31
|
+
obj2 instanceof PdfNumber ||
|
|
32
|
+
obj2 instanceof PdfNull ||
|
|
33
|
+
obj2 instanceof PdfBoolean);
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdf-lite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
],
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"pako": "2.1.0",
|
|
57
|
-
"pki-lite": "^1.0.
|
|
58
|
-
"pki-lite-crypto-extended": "^1.0.
|
|
57
|
+
"pki-lite": "^1.0.14",
|
|
58
|
+
"pki-lite-crypto-extended": "^1.0.14"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"test:acceptance": "vitest run test/acceptance",
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { PdfDocument } from '../pdf/pdf-document.js';
|
|
2
|
-
import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
|
|
3
|
-
import { PdfArray } from '../core/objects/pdf-array.js';
|
|
4
|
-
import { PdfString } from '../core/objects/pdf-string.js';
|
|
5
|
-
import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
|
|
6
|
-
import { PdfIndirectObject } from '../core/objects/pdf-indirect-object.js';
|
|
7
|
-
import { PdfBoolean } from '../core/objects/pdf-boolean.js';
|
|
8
|
-
import { PdfNumber } from '../core/objects/pdf-number.js';
|
|
9
|
-
import { PdfFormField } from './fields/PdfFormField.js';
|
|
10
|
-
import './fields/PdfTextFormField.js';
|
|
11
|
-
import './fields/PdfButtonFormField.js';
|
|
12
|
-
import './fields/PdfChoiceFormField.js';
|
|
13
|
-
import './fields/PdfSignatureFormField.js';
|
|
14
|
-
import type { FormContext } from './fields/types.js';
|
|
15
|
-
export type PdfDefaultResourcesDictionary = PdfDictionary<{
|
|
16
|
-
Font?: PdfDictionary;
|
|
17
|
-
ProcSet?: PdfArray;
|
|
18
|
-
ExtGState?: PdfDictionary;
|
|
19
|
-
ColorSpace?: PdfDictionary;
|
|
20
|
-
Pattern?: PdfDictionary;
|
|
21
|
-
Shading?: PdfDictionary;
|
|
22
|
-
XObject?: PdfDictionary;
|
|
23
|
-
}>;
|
|
24
|
-
export declare class PdfAcroForm<T extends Record<string, string> = Record<string, string>> extends PdfIndirectObject<PdfDictionary<{
|
|
25
|
-
Fields: PdfArray<PdfObjectReference>;
|
|
26
|
-
NeedAppearances?: PdfBoolean;
|
|
27
|
-
SigFlags?: PdfNumber;
|
|
28
|
-
CO?: PdfArray<PdfObjectReference>;
|
|
29
|
-
DR?: PdfDefaultResourcesDictionary;
|
|
30
|
-
DA?: PdfString;
|
|
31
|
-
Q?: PdfNumber;
|
|
32
|
-
XFA?: PdfDictionary;
|
|
33
|
-
}>> implements FormContext<PdfFormField> {
|
|
34
|
-
fields: PdfFormField[];
|
|
35
|
-
private _fontEncodingCache?;
|
|
36
|
-
private document?;
|
|
37
|
-
constructor(options?: {
|
|
38
|
-
other?: PdfIndirectObject;
|
|
39
|
-
fields?: PdfFormField[];
|
|
40
|
-
document?: PdfDocument;
|
|
41
|
-
});
|
|
42
|
-
private get fontEncodingCache();
|
|
43
|
-
get fontEncodingMaps(): Map<string, Map<number, string>>;
|
|
44
|
-
isModified(): boolean;
|
|
45
|
-
get needAppearances(): boolean;
|
|
46
|
-
set needAppearances(value: boolean);
|
|
47
|
-
get signatureFlags(): number;
|
|
48
|
-
set signatureFlags(flags: number);
|
|
49
|
-
get defaultAppearance(): string | null;
|
|
50
|
-
set defaultAppearance(da: string);
|
|
51
|
-
get defaultQuadding(): number;
|
|
52
|
-
set defaultQuadding(q: number);
|
|
53
|
-
get defaultResources(): PdfDefaultResourcesDictionary | null;
|
|
54
|
-
set defaultResources(resources: PdfDefaultResourcesDictionary | null);
|
|
55
|
-
setValues(values: Partial<T>): void;
|
|
56
|
-
importData(fields: T): void;
|
|
57
|
-
exportData(): Partial<T>;
|
|
58
|
-
getFontEncodingMap(fontName: string): Promise<Map<number, string> | null>;
|
|
59
|
-
static fromDocument(document: PdfDocument): Promise<PdfAcroForm | null>;
|
|
60
|
-
private cacheAllFontEncodings;
|
|
61
|
-
private updatePageAnnotations;
|
|
62
|
-
write(document: PdfDocument): Promise<void>;
|
|
63
|
-
}
|