@f-o-t/e-signature 1.4.1 → 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/CHANGELOG.md +260 -0
- package/README.md +26 -0
- package/bunfig.toml +3 -0
- package/package.json +19 -35
- package/dist/appearance.d.ts +0 -28
- package/dist/appearance.d.ts.map +0 -1
- package/dist/batch.d.ts +0 -61
- package/dist/batch.d.ts.map +0 -1
- package/dist/detect-position.d.ts +0 -13
- package/dist/detect-position.d.ts.map +0 -1
- package/dist/icp-brasil.d.ts +0 -60
- package/dist/icp-brasil.d.ts.map +0 -1
- package/dist/index-cj97mfbz.js +0 -684
- package/dist/index-cj97mfbz.js.map +0 -15
- package/dist/index.d.ts +0 -17
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -88
- package/dist/index.js.map +0 -10
- package/dist/plugins/react/index.d.ts +0 -58
- package/dist/plugins/react/index.d.ts.map +0 -1
- package/dist/plugins/react/index.js +0 -85
- package/dist/plugins/react/index.js.map +0 -10
- package/dist/schemas.d.ts +0 -48
- package/dist/schemas.d.ts.map +0 -1
- package/dist/sign-pdf.d.ts +0 -39
- package/dist/sign-pdf.d.ts.map +0 -1
- package/dist/timestamp.d.ts +0 -32
- package/dist/timestamp.d.ts.map +0 -1
- package/dist/types.d.ts +0 -104
- package/dist/types.d.ts.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.6.0] - 2026-03-05
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Web Worker signing via `signPdfInWorker()` — runs signing off the main thread to prevent browser freezes (`plugins/worker` + `plugins/worker-entry`)
|
|
13
|
+
|
|
14
|
+
## [1.5.0] - 2026-03-04
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Signature appearance "Signatário" text now renders correctly instead of garbled "Signat`jrio" — fixed by WinAnsiEncoding support in `@f-o-t/pdf`
|
|
18
|
+
- Auto-appearance width increased from 350pt to 420pt to prevent text clipping
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Signing no longer parses the P12 certificate twice — uses `parseCertificateFromDer` to build display info from the already-extracted DER bytes, eliminating ~90ms of redundant PBKDF2 key derivation
|
|
22
|
+
- Bump `@f-o-t/pdf` dependency to `^0.4.1` (100x faster `loadPdf` via object position indexing)
|
|
23
|
+
- Bump `@f-o-t/digital-certificate` dependency to `^2.3.1`
|
|
24
|
+
- Full auto-sign on a 100-page 571KB PDF: **732ms → 173ms** (4.2x faster)
|
|
25
|
+
|
|
26
|
+
## [1.4.1] - 2026-03-04
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Reduced signature appearance font sizes (header 12→9pt, body 10→7.5pt, link 8→6pt) and QR code max size (100→80pt) to prevent text overflow in the stamp box
|
|
30
|
+
- Signature position detection now only scans the last 3 pages instead of every page, fixing browser freezes on large multi-page PDFs
|
|
31
|
+
|
|
32
|
+
## [1.4.0] - 2026-03-04
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
- `appearance: "auto"` now places a signature stamp on every page of the PDF (previously only placed on one page)
|
|
36
|
+
- Bump `@f-o-t/pdf` dependency to `^0.4.0`
|
|
37
|
+
|
|
38
|
+
## [1.3.1] - 2026-03-04
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- `buildSignaturePolicy()` now uses `AbortSignal.timeout(10000)` when fetching the ICP-Brasil policy DER file — previously the fetch had no timeout, causing `signPdf` to hang indefinitely when the policy server was unreachable or blocked by browser mixed-content security (HTTP from HTTPS page)
|
|
42
|
+
|
|
43
|
+
## [1.3.0] - 2026-03-04
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
- `detectSigningPosition()` function for automatic signature placement using weighted text search
|
|
47
|
+
- `appearance: "auto"` option in `signPdf()` for auto-detected positioning
|
|
48
|
+
- `DetectedPosition` and `DetectPositionOptions` types
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
- Visual signature appearance redesigned with bordered box, green ICP-Brasil header, and structured fields (Signatário, Empresa, CNPJ/CPF, Data, Certificado)
|
|
52
|
+
- QR code now points to `https://validar.iti.gov.br`
|
|
53
|
+
- Reference link "validar.iti.gov.br" displayed below signature box
|
|
54
|
+
|
|
55
|
+
## [1.2.18] - 2026-02-20
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
- Bump `@f-o-t/qrcode` dependency to `^1.0.2` to pick up browser-compatible PNG compression (`fflate` `zlibSync` replacing `node:zlib` `deflateSync`) — QR code generation now works in browser environments without a `zlib` polyfill
|
|
59
|
+
|
|
60
|
+
## [1.2.17] - 2026-02-19
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
- `signPdf` now `await`s `parsePkcs12` after it was made async in `@f-o-t/crypto` — no behaviour change for consumers, but PKCS#12 decryption now uses SubtleCrypto PBKDF2 natively when available, preventing main-thread blocking on PBES2-encrypted PFX files
|
|
64
|
+
- `useSignPdf` (React plugin) calls `signPdf` directly instead of spawning a `Worker` — removes the brittle `.ts` worker URL that broke in consumer bundles; the hook still exposes the same async API so UI stays responsive
|
|
65
|
+
|
|
66
|
+
## [1.2.16] - 2026-02-19
|
|
67
|
+
|
|
68
|
+
### Changed
|
|
69
|
+
|
|
70
|
+
- `useSignPdf` now offloads all signing work (PKCS#12 parsing, RSA crypto, ICP-Brasil policy fetch, RFC 3161 TSA timestamp) to a dedicated Web Worker — the main thread stays fully responsive during signing, eliminating the browser freeze that occurred with large PDFs or slow TSA servers
|
|
71
|
+
- TSA timestamp fetch is preserved inside the worker, so ICP-Brasil signatures remain fully valid
|
|
72
|
+
- Bump `@f-o-t/cli` devDependency to `^1.0.6` to pick up automatic worker file compilation and plugin declaration generation — `dist/plugins/react/` now ships `sign-pdf.worker.js`, `index.d.ts`, and `sign-pdf.worker.d.ts`
|
|
73
|
+
|
|
74
|
+
## [1.2.15] - 2026-02-19
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
|
|
78
|
+
- Bump `@f-o-t/cli` devDependency to `^1.0.5` to pick up the `module` condition fix in `syncPackageJsonExports` — `fot build` now correctly writes `module` alongside `import` and `default` in the generated exports, ensuring Vite/rolldown can resolve entry points without a manual `node_modules` patch
|
|
79
|
+
|
|
80
|
+
## [1.2.14] - 2026-02-19
|
|
81
|
+
|
|
82
|
+
### Changed
|
|
83
|
+
|
|
84
|
+
- Bump `@f-o-t/config` devDependency to `^1.0.5` to pick up the `module` condition fix in the package-json generator
|
|
85
|
+
|
|
86
|
+
## [1.2.13] - 2026-02-19
|
|
87
|
+
|
|
88
|
+
### Fixed
|
|
89
|
+
|
|
90
|
+
- Add `module` condition to `package.json` exports (both `.` and `./plugins/react`) so Vite/rolldown resolving under conditions `["module", "browser", "development", "import"]` can locate the ESM entry points — the `module` condition was absent, causing a "not exported under the conditions" build error when the app was started with a newer Vite version
|
|
91
|
+
|
|
92
|
+
## [1.2.12] - 2026-02-19
|
|
93
|
+
|
|
94
|
+
### Fixed
|
|
95
|
+
|
|
96
|
+
- Add `import` condition to `package.json` exports (both `.` and `./plugins/react`) so Vite and other bundlers resolving under conditions `["module", "browser", "import"]` can locate the ESM entry points — previously only `default` was present, causing a "not exported under the conditions" error when importing `@f-o-t/e-signature/plugins/react`
|
|
97
|
+
|
|
98
|
+
## [1.2.11] - 2026-02-19
|
|
99
|
+
|
|
100
|
+
### Fixed
|
|
101
|
+
|
|
102
|
+
- Added `"./plugins/react"` to the `exports` field in `package.json`; the entry was missing from the published manifest because `fot build` did not previously sync `exports` from `fot.config.ts` — Vite/Rolldown (and any bundler respecting the `exports` map) would reject the import with *"not exported under the conditions [module, browser, …]"*
|
|
103
|
+
|
|
104
|
+
## [1.2.10] - 2026-02-19
|
|
105
|
+
|
|
106
|
+
### Fixed
|
|
107
|
+
- Corrected TypeScript errors in `react.test.tsx`: cast `mockSignPdf.mock.calls[0]` to `[Uint8Array, unknown]` to match the two-argument mock signature; added explicit cast on `thrown` to `Error | null` to resolve incorrect `never` narrowing; typed `firstPromise` as `Promise<Uint8Array<ArrayBufferLike>>` and cast at the `mockImplementationOnce` call site to satisfy the `ArrayBuffer` vs `ArrayBufferLike` assignability constraint
|
|
108
|
+
|
|
109
|
+
## [1.2.9] - 2026-02-19
|
|
110
|
+
|
|
111
|
+
### Changed
|
|
112
|
+
- Updated `@f-o-t/digital-certificate` dependency to `^2.3.0` to pick up browser-compatible `parseCertificate` (`Uint8Array` parameter) and cross-platform base64 helpers
|
|
113
|
+
|
|
114
|
+
### Fixed
|
|
115
|
+
- `signPdf` no longer wraps `opts.certificate.p12` in `Buffer.from()` before passing it to `parseCertificate`; the `Uint8Array` is passed directly, removing the last Node-only `Buffer` usage in the signing path — `signPdf` now runs in browser environments without polyfills
|
|
116
|
+
|
|
117
|
+
## [1.2.8] - 2026-02-19
|
|
118
|
+
|
|
119
|
+
### Changed
|
|
120
|
+
- Updated `@f-o-t/crypto` dependency to `^1.2.0` and `@f-o-t/digital-certificate` to `^2.2.2` to pick up pure-TS PBKDF2/HMAC optimizations (~8× faster PBKDF2-SHA256, ~3× faster `parsePkcs12`); `signPdf` is now viable on the client side (browser/Edge Runtime) without OpenSSL
|
|
121
|
+
|
|
122
|
+
## [1.2.7] - 2026-02-18
|
|
123
|
+
|
|
124
|
+
### Fixed
|
|
125
|
+
- `signPdf` now passes `appearancePage` to `saveWithPlaceholder` so the PDF widget annotation is placed on the same page as the visual signature; previously the annotation always landed on page 0 regardless of where the appearance was drawn, causing PDF readers to navigate to the wrong page when clicking the signature field
|
|
126
|
+
- Signature placeholder size is now computed dynamically from the actual certificate chain byte length (`certChainBytes * 2 + 8 KB base + 4 KB for TSA`) instead of a fixed 16 KB, preventing "signature too large" failures for certificate chains with 5+ certificates or large RSA keys; the floor remains 16 KB for small chains
|
|
127
|
+
- `parsePkcs12` is now called only once (step 1) and the result reused throughout `signPdf`; the previous code parsed the same PKCS#12 twice (steps 1 and 6), doubling CPU and memory cost of certificate parsing for every `signPdf` call
|
|
128
|
+
- Updated `@f-o-t/pdf` dependency floor to `^0.3.8` to pick up nested page tree recursion, MediaBox inheritance fix, and correct widget annotation page placement
|
|
129
|
+
|
|
130
|
+
## [1.2.6] - 2026-02-18
|
|
131
|
+
|
|
132
|
+
### Fixed
|
|
133
|
+
- Updated `@f-o-t/pdf` dependency floor to `^0.3.7` to pick up the parser memory fix: PDF bytes are now decoded to a latin1 string exactly once per `signPdf` call (previously decoded O(pages) times), and `embedSignature` / `extractBytesToSign` no longer allocate unnecessary full-PDF-sized copies — together these eliminate the JS heap OOM that users hit when signing PDFs with more than a few pages
|
|
134
|
+
|
|
135
|
+
## [1.2.5] - 2026-02-18
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
- `extractSignatureValue` now locates `signerInfos` as the last child of `SignedData` (`.at(-1)`) instead of hardcoded index `[4]`; the previous index assumed `certificates [0]` was always present and `crls [1]` always absent, which would produce a wrong timestamp over external CMS blobs with a different layout
|
|
139
|
+
- Updated `@f-o-t/crypto` dependency floor to `^1.1.0` to pick up `appendUnauthAttributes` and the corresponding signerInfos fix
|
|
140
|
+
|
|
141
|
+
## [1.2.4] - 2026-02-18
|
|
142
|
+
|
|
143
|
+
### Fixed
|
|
144
|
+
- `signPdf` with `appearances` array no longer generates and embeds a separate QR image XObject per entry; the QR image is pre-computed once and shared across all appearances, collapsing N `generateQrCode` + `doc.embedPng` calls into 1 and preventing O(N) heap growth that caused JavaScript heap OOM in Vercel Edge Runtime for PDFs with 5+ appearances
|
|
145
|
+
- Updated `@f-o-t/pdf` dependency floor to `^0.3.6` to pick up in-place ByteRange patching and binary `findByteRange` (eliminates up to 3× PDF-size string allocations per sign call)
|
|
146
|
+
|
|
147
|
+
## [1.2.3] - 2026-02-18
|
|
148
|
+
|
|
149
|
+
### Fixed
|
|
150
|
+
- `signPdf` with `timestamp: true` now correctly embeds the RFC 3161 timestamp token as an unauthenticated attribute (OID `1.2.840.113549.1.9.16.2.14`) inside the CMS SignerInfo; previously the token was requested from the TSA but silently discarded, leaving signatures indistinguishable from untimestamped ones
|
|
151
|
+
|
|
152
|
+
## [1.2.2] - 2026-02-18
|
|
153
|
+
|
|
154
|
+
### Fixed
|
|
155
|
+
- `onTimestampError` schema now uses Zod v4 `z.function({ input, output })` API instead of the removed `z.function().args().returns()` (Zod v3) — fixes `TypeError: z.function(...).args is not a function` at import time
|
|
156
|
+
|
|
157
|
+
## [1.2.1] - 2026-02-18
|
|
158
|
+
|
|
159
|
+
### Added
|
|
160
|
+
- `tsaTimeout?: number` option on `PdfSignOptions` — configurable timeout per TSA attempt (default: 10000ms)
|
|
161
|
+
- `tsaRetries?: number` option on `PdfSignOptions` — number of retry attempts after the initial request fails; total attempts = `1 + tsaRetries` (default: `0`)
|
|
162
|
+
- `tsaFallbackUrls?: string[]` option on `PdfSignOptions` — fallback TSA servers tried in order after primary fails; exponential backoff (1s, 2s) between primary retries only
|
|
163
|
+
- `onTimestampError?: (error: unknown) => void` option on `PdfSignOptions` — optional callback invoked when timestamping fails (non-fatal); use for logging or metrics
|
|
164
|
+
- `signPdf` now accepts `ReadableStream<Uint8Array>` as PDF input in addition to `Uint8Array`; internally accumulates chunks before signing
|
|
165
|
+
- `signPdfBatch(files, options): AsyncGenerator<BatchSignEvent>` — sign multiple PDFs sequentially, yielding progress events per file; yields control between files to avoid blocking the event loop
|
|
166
|
+
- `signPdfBatchToArray(files, options): Promise<...>` — convenience wrapper for batch signing that collects results into an array
|
|
167
|
+
- `BatchSignInput` and `BatchSignEvent` types exported from the package
|
|
168
|
+
|
|
169
|
+
### Fixed
|
|
170
|
+
- TSA errors now include the server URL and original message in the error text instead of an opaque `fetch failed`
|
|
171
|
+
- `tsaRetries` semantics corrected: now means retries *after* the initial attempt (`1 + tsaRetries` total); default changed from `1` to `0` so the default behavior (1 attempt) is unchanged
|
|
172
|
+
- `batch_complete.totalFiles` now reflects the number of files actually processed (non-falsy entries) instead of the raw array length, ensuring it always equals the number of `file_start` events emitted
|
|
173
|
+
|
|
174
|
+
## [1.1.0] - 2026-02-18
|
|
175
|
+
|
|
176
|
+
### Added
|
|
177
|
+
- `appearances?: SignatureAppearance[]` field on `PdfSignOptions` — renders a visual stamp on each specified page in a single `signPdf` call, enabling multi-page document stamping while the cryptographic signature is still applied once over the entire document
|
|
178
|
+
|
|
179
|
+
## [1.0.7] - 2026-02-15
|
|
180
|
+
|
|
181
|
+
### Fixed
|
|
182
|
+
- Signature appearance Y coordinate now uses top-left origin (distance from top of page) matching user expectations, instead of raw PDF bottom-left origin which caused signatures placed at the bottom to appear at the top
|
|
183
|
+
|
|
184
|
+
## [1.0.6] - 2026-02-15
|
|
185
|
+
|
|
186
|
+
### Changed
|
|
187
|
+
- Updated `@f-o-t/pdf` dependency from `^0.3.3` to `^0.3.4`
|
|
188
|
+
|
|
189
|
+
### Fixed
|
|
190
|
+
- Visual signature appearance no longer renders mirrored/upside-down on PDFs with transformed coordinate systems (fixed via @f-o-t/pdf@0.3.4 graphics state isolation)
|
|
191
|
+
|
|
192
|
+
## [1.0.5] - 2026-02-15
|
|
193
|
+
|
|
194
|
+
### Changed
|
|
195
|
+
- Updated `@f-o-t/pdf` dependency from `^0.3.2` to `^0.3.3`
|
|
196
|
+
|
|
197
|
+
### Fixed
|
|
198
|
+
- QR code and certificate info text now render side-by-side within the same bounding box instead of at different page positions (fixed via @f-o-t/pdf@0.3.3 coordinate system fix)
|
|
199
|
+
|
|
200
|
+
## [1.0.4] - 2026-02-14
|
|
201
|
+
|
|
202
|
+
### Changed
|
|
203
|
+
- Updated `@f-o-t/digital-certificate` dependency from `^1.0.5` to `^2.2.0`
|
|
204
|
+
- Updated `@f-o-t/pdf` dependency from `^0.3.1` to `^0.3.2`
|
|
205
|
+
|
|
206
|
+
## [1.0.3] - 2026-02-14
|
|
207
|
+
|
|
208
|
+
### Changed
|
|
209
|
+
- Updated `@f-o-t/pdf` dependency from `^0.3.0` to `^0.3.1`
|
|
210
|
+
|
|
211
|
+
### Fixed
|
|
212
|
+
- Visual signature text now renders upright instead of upside-down/mirrored (fixed via @f-o-t/pdf@0.3.1 dependency upgrade)
|
|
213
|
+
|
|
214
|
+
## [1.0.2] - 2026-02-14
|
|
215
|
+
|
|
216
|
+
### Changed
|
|
217
|
+
- Updated `@f-o-t/pdf` dependency from `^0.2.0` to `^0.3.0`
|
|
218
|
+
|
|
219
|
+
### Fixed
|
|
220
|
+
- Visual signature appearances no longer corrupt document fonts (fixed via @f-o-t/pdf@0.3.0 dependency upgrade)
|
|
221
|
+
- PDFs from @react-pdf/renderer with CIDFont fonts now render correctly after signing with visual appearance
|
|
222
|
+
|
|
223
|
+
## [1.0.1] - 2026-02-14
|
|
224
|
+
|
|
225
|
+
### Fixed
|
|
226
|
+
- Internal dependency updates
|
|
227
|
+
|
|
228
|
+
## [1.0.0] - 2026-02-13
|
|
229
|
+
|
|
230
|
+
### Added
|
|
231
|
+
- Initial release of PAdES PDF signing library
|
|
232
|
+
- `signPdf` function for signing PDFs with digital certificates
|
|
233
|
+
- ICP-Brasil compliance with `signing-certificate-v2` and `signature-policy` attributes
|
|
234
|
+
- Visual signature appearance with QR code and certificate info
|
|
235
|
+
- RFC 3161 timestamp client using native `fetch`
|
|
236
|
+
- Zod schema validation for all inputs
|
|
237
|
+
- Support for DocMDP permissions (1, 2, 3)
|
|
238
|
+
|
|
239
|
+
[1.2.18]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.17...@f-o-t/e-signature@1.2.18
|
|
240
|
+
[1.2.16]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.15...@f-o-t/e-signature@1.2.16
|
|
241
|
+
[1.2.15]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.14...@f-o-t/e-signature@1.2.15
|
|
242
|
+
[1.2.14]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.13...@f-o-t/e-signature@1.2.14
|
|
243
|
+
[1.2.13]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.12...@f-o-t/e-signature@1.2.13
|
|
244
|
+
[1.2.12]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.11...@f-o-t/e-signature@1.2.12
|
|
245
|
+
[1.2.11]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.10...@f-o-t/e-signature@1.2.11
|
|
246
|
+
[1.2.9]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.8...@f-o-t/e-signature@1.2.9
|
|
247
|
+
[1.2.8]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.7...@f-o-t/e-signature@1.2.8
|
|
248
|
+
[1.2.7]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.6...@f-o-t/e-signature@1.2.7
|
|
249
|
+
[1.2.6]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.5...@f-o-t/e-signature@1.2.6
|
|
250
|
+
[1.2.5]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.2.4...@f-o-t/e-signature@1.2.5
|
|
251
|
+
[1.2.0]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.1.0...@f-o-t/e-signature@1.2.0
|
|
252
|
+
[1.1.0]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.0.7...@f-o-t/e-signature@1.1.0
|
|
253
|
+
[1.0.7]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.0.6...@f-o-t/e-signature@1.0.7
|
|
254
|
+
[1.0.6]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.0.5...@f-o-t/e-signature@1.0.6
|
|
255
|
+
[1.0.5]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.0.4...@f-o-t/e-signature@1.0.5
|
|
256
|
+
[1.0.4]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.0.3...@f-o-t/e-signature@1.0.4
|
|
257
|
+
[1.0.3]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.0.2...@f-o-t/e-signature@1.0.3
|
|
258
|
+
[1.0.2]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.0.1...@f-o-t/e-signature@1.0.2
|
|
259
|
+
[1.0.1]: https://github.com/F-O-T/libraries/compare/@f-o-t/e-signature@1.0.0...@f-o-t/e-signature@1.0.1
|
|
260
|
+
[1.0.0]: https://github.com/F-O-T/libraries/releases/tag/@f-o-t/e-signature@1.0.0
|
package/README.md
CHANGED
|
@@ -68,6 +68,32 @@ function SignForm() {
|
|
|
68
68
|
|
|
69
69
|
`pdf` and `p12` accept `File`, `Blob`, or `Uint8Array` — the hook converts `File`/`Blob` to `Uint8Array` automatically before calling `signPdf`.
|
|
70
70
|
|
|
71
|
+
## Web Worker Signing
|
|
72
|
+
|
|
73
|
+
Runs signing off the main thread to prevent browser freezes.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { signPdfInWorker } from "@f-o-t/e-signature/plugins/worker";
|
|
77
|
+
|
|
78
|
+
const worker = new Worker(
|
|
79
|
+
new URL("@f-o-t/e-signature/plugins/worker-entry", import.meta.url),
|
|
80
|
+
{ type: "module" },
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const signed = await signPdfInWorker(worker, pdfBytes, {
|
|
84
|
+
certificate: { p12, password: "secret" },
|
|
85
|
+
appearance: "auto",
|
|
86
|
+
policy: "pades-icp-brasil",
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Reuse the worker for multiple signings, or terminate when done
|
|
90
|
+
worker.terminate();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `signPdfInWorker(worker: Worker, pdf: Uint8Array, options: PdfSignOptions): Promise<Uint8Array>`
|
|
94
|
+
|
|
95
|
+
Same as `signPdf` but takes a `Worker` as the first argument. PDF bytes are transferred (zero-copy) to the worker thread.
|
|
96
|
+
|
|
71
97
|
## Automatic Signature Positioning
|
|
72
98
|
|
|
73
99
|
### Using `appearance: "auto"`
|
package/bunfig.toml
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@f-o-t/e-signature",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "PAdES PDF signing with ICP-Brasil compliance",
|
|
3
|
+
"version": "1.6.0",
|
|
5
4
|
"type": "module",
|
|
6
5
|
"main": "./dist/index.js",
|
|
7
6
|
"types": "./dist/index.d.ts",
|
|
@@ -17,44 +16,29 @@
|
|
|
17
16
|
"module": "./dist/plugins/react/index.js",
|
|
18
17
|
"import": "./dist/plugins/react/index.js",
|
|
19
18
|
"default": "./dist/plugins/react/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./plugins/worker": {
|
|
21
|
+
"types": "./dist/plugins/worker/index.d.ts",
|
|
22
|
+
"module": "./dist/plugins/worker/index.js",
|
|
23
|
+
"import": "./dist/plugins/worker/index.js",
|
|
24
|
+
"default": "./dist/plugins/worker/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./plugins/worker-entry": {
|
|
27
|
+
"types": "./dist/plugins/worker-entry/index.d.ts",
|
|
28
|
+
"module": "./dist/plugins/worker-entry/index.js",
|
|
29
|
+
"import": "./dist/plugins/worker-entry/index.js",
|
|
30
|
+
"default": "./dist/plugins/worker-entry/index.js"
|
|
20
31
|
}
|
|
21
32
|
},
|
|
22
|
-
"files": [
|
|
23
|
-
"dist"
|
|
24
|
-
],
|
|
25
33
|
"scripts": {
|
|
26
|
-
"build": "
|
|
27
|
-
"test": "
|
|
28
|
-
"lint": "
|
|
29
|
-
"format": "
|
|
30
|
-
"check": "bun x --bun fot check"
|
|
31
|
-
},
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"@f-o-t/asn1": "^1.0.0",
|
|
34
|
-
"@f-o-t/crypto": "^1.3.0",
|
|
35
|
-
"@f-o-t/digital-certificate": "^2.3.0",
|
|
36
|
-
"@f-o-t/pdf": "^0.4.0",
|
|
37
|
-
"@f-o-t/qrcode": "^1.0.2",
|
|
38
|
-
"zod": "^4.3.6"
|
|
34
|
+
"build": "fot build",
|
|
35
|
+
"test": "fot test",
|
|
36
|
+
"lint": "fot lint",
|
|
37
|
+
"format": "fot format"
|
|
39
38
|
},
|
|
40
39
|
"devDependencies": {
|
|
41
|
-
"@f-o-t/cli": "
|
|
42
|
-
"@f-o-t/config": "
|
|
43
|
-
"@testing-library/react": "^16.0.0",
|
|
44
|
-
"@types/bun": "latest",
|
|
45
|
-
"@types/react": "^19.0.0",
|
|
46
|
-
"@types/react-dom": "^19.0.0",
|
|
47
|
-
"happy-dom": "^20.6.3",
|
|
48
|
-
"react": "^19.0.0",
|
|
49
|
-
"react-dom": "^19.0.0"
|
|
50
|
-
},
|
|
51
|
-
"peerDependencies": {
|
|
52
|
-
"react": ">=18.0.0"
|
|
53
|
-
},
|
|
54
|
-
"peerDependenciesMeta": {
|
|
55
|
-
"react": {
|
|
56
|
-
"optional": true
|
|
57
|
-
}
|
|
40
|
+
"@f-o-t/cli": "workspace:*",
|
|
41
|
+
"@f-o-t/config": "workspace:*"
|
|
58
42
|
},
|
|
59
43
|
"repository": {
|
|
60
44
|
"type": "git",
|
package/dist/appearance.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Visual Signature Appearance
|
|
3
|
-
*
|
|
4
|
-
* Draws certificate information and QR code on the PDF page
|
|
5
|
-
* following the ICP-Brasil standard visual signature layout.
|
|
6
|
-
*/
|
|
7
|
-
import type { CertificateInfo } from "@f-o-t/digital-certificate";
|
|
8
|
-
import type { PdfDocument, PdfImage, PdfPage } from "@f-o-t/pdf/plugins/editing";
|
|
9
|
-
import type { QrCodeConfig, SignatureAppearance } from "./types.ts";
|
|
10
|
-
/**
|
|
11
|
-
* Draw the visual signature appearance on a PDF page.
|
|
12
|
-
*
|
|
13
|
-
* Includes optional QR code and certificate information text
|
|
14
|
-
* inside a bordered rectangle following ICP-Brasil layout.
|
|
15
|
-
*/
|
|
16
|
-
export declare function drawSignatureAppearance(doc: PdfDocument, page: PdfPage, appearance: SignatureAppearance, certInfo: CertificateInfo | null, options: {
|
|
17
|
-
reason?: string;
|
|
18
|
-
location?: string;
|
|
19
|
-
qrCode?: QrCodeConfig;
|
|
20
|
-
pdfData: Uint8Array;
|
|
21
|
-
preEmbeddedQr?: PdfImage;
|
|
22
|
-
}): void;
|
|
23
|
-
/**
|
|
24
|
-
* Pre-compute the QR code image and embed it once into the PDF document.
|
|
25
|
-
* Call this before an appearances loop so all appearances share a single XObject.
|
|
26
|
-
*/
|
|
27
|
-
export declare function precomputeSharedQrImage(doc: PdfDocument, certInfo: CertificateInfo | null, pdfData: Uint8Array, qrConfig?: QrCodeConfig): PdfImage;
|
|
28
|
-
//# sourceMappingURL=appearance.d.ts.map
|
package/dist/appearance.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"appearance.d.ts","sourceRoot":"","sources":["../src/appearance.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EACT,WAAW,EACX,QAAQ,EACR,OAAO,EACT,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAIpE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACpC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,eAAe,GAAG,IAAI,EAChC,OAAO,EAAE;IACN,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,UAAU,CAAC;IACpB,aAAa,CAAC,EAAE,QAAQ,CAAC;CAC3B,GACD,IAAI,CA8DN;AAgGD;;;GAGG;AACH,wBAAgB,uBAAuB,CACpC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,eAAe,GAAG,IAAI,EAChC,OAAO,EAAE,UAAU,EACnB,QAAQ,CAAC,EAAE,YAAY,GACvB,QAAQ,CAIV"}
|
package/dist/batch.d.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { PdfSignOptions } from "./types.ts";
|
|
2
|
-
/**
|
|
3
|
-
* Input for a single PDF in a batch signing operation.
|
|
4
|
-
*/
|
|
5
|
-
export type BatchSignInput = {
|
|
6
|
-
/** Filename for identification in events */
|
|
7
|
-
filename: string;
|
|
8
|
-
/** PDF content as Uint8Array or ReadableStream */
|
|
9
|
-
pdf: Uint8Array | ReadableStream<Uint8Array>;
|
|
10
|
-
/** Per-file option overrides merged with base options */
|
|
11
|
-
options?: Partial<PdfSignOptions>;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Events emitted during batch signing.
|
|
15
|
-
*/
|
|
16
|
-
export type BatchSignEvent = {
|
|
17
|
-
type: "file_start";
|
|
18
|
-
fileIndex: number;
|
|
19
|
-
filename: string;
|
|
20
|
-
} | {
|
|
21
|
-
type: "file_complete";
|
|
22
|
-
fileIndex: number;
|
|
23
|
-
filename: string;
|
|
24
|
-
signed: Uint8Array;
|
|
25
|
-
} | {
|
|
26
|
-
type: "file_error";
|
|
27
|
-
fileIndex: number;
|
|
28
|
-
filename: string;
|
|
29
|
-
error: string;
|
|
30
|
-
} | {
|
|
31
|
-
type: "batch_complete";
|
|
32
|
-
totalFiles: number;
|
|
33
|
-
errorCount: number;
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Sign multiple PDFs sequentially, yielding progress events.
|
|
37
|
-
*
|
|
38
|
-
* Yields control between each signing operation to prevent blocking
|
|
39
|
-
* the event loop under bulk load.
|
|
40
|
-
*
|
|
41
|
-
* @param files - Array of PDFs with filename and optional per-file options
|
|
42
|
-
* @param options - Base signing options (per-file options override these)
|
|
43
|
-
* @yields BatchSignEvent for each file start, completion, error, and batch complete
|
|
44
|
-
*/
|
|
45
|
-
export declare function signPdfBatch(files: BatchSignInput[], options: PdfSignOptions): AsyncGenerator<BatchSignEvent>;
|
|
46
|
-
/**
|
|
47
|
-
* Sign multiple PDFs sequentially, collecting all results.
|
|
48
|
-
*
|
|
49
|
-
* Convenience wrapper around {@link signPdfBatch} that collects all events
|
|
50
|
-
* into an array of results.
|
|
51
|
-
*
|
|
52
|
-
* @param files - Array of PDFs with filename and optional per-file options
|
|
53
|
-
* @param options - Base signing options
|
|
54
|
-
* @returns Array of results with signed PDF bytes or error per file
|
|
55
|
-
*/
|
|
56
|
-
export declare function signPdfBatchToArray(files: BatchSignInput[], options: PdfSignOptions): Promise<{
|
|
57
|
-
filename: string;
|
|
58
|
-
signed?: Uint8Array;
|
|
59
|
-
error?: string;
|
|
60
|
-
}[]>;
|
|
61
|
-
//# sourceMappingURL=batch.d.ts.map
|
package/dist/batch.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC1B,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,GAAG,EAAE,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC7C,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GACrB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC3D;IACG,IAAI,EAAE,eAAe,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;CACrB,GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE;;;;;;;;;GASG;AACH,wBAAuB,YAAY,CAChC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,cAAc,GACvB,cAAc,CAAC,cAAc,CAAC,CAsChC;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACtC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,cAAc,GACvB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAoBtE"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { DetectedPosition, DetectPositionOptions } from "./types.ts";
|
|
2
|
-
/**
|
|
3
|
-
* Detect the best position to place a digital signature on a PDF.
|
|
4
|
-
*
|
|
5
|
-
* Uses weighted scoring across three signal types:
|
|
6
|
-
* - Signer name match (weight 3)
|
|
7
|
-
* - Horizontal line patterns (weight 2)
|
|
8
|
-
* - Signature keywords (weight 1)
|
|
9
|
-
*
|
|
10
|
-
* Returns null if the PDF cannot be parsed.
|
|
11
|
-
*/
|
|
12
|
-
export declare function detectSigningPosition(pdfData: Uint8Array, options?: DetectPositionOptions): DetectedPosition | null;
|
|
13
|
-
//# sourceMappingURL=detect-position.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detect-position.d.ts","sourceRoot":"","sources":["../src/detect-position.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAoB1E;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAClC,OAAO,EAAE,UAAU,EACnB,OAAO,GAAE,qBAA0B,GACnC,gBAAgB,GAAG,IAAI,CAqIzB"}
|
package/dist/icp-brasil.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ICP-Brasil Attributes for PAdES Signatures
|
|
3
|
-
*
|
|
4
|
-
* Implements the id-aa-signingCertificateV2 (RFC 5035) and
|
|
5
|
-
* id-aa-ets-sigPolicyId attributes required by ICP-Brasil.
|
|
6
|
-
*
|
|
7
|
-
* Uses @f-o-t/asn1 for ASN.1 construction and @f-o-t/crypto for hashing.
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Clear the cached signature policy data.
|
|
11
|
-
* Useful for testing or forcing a re-download.
|
|
12
|
-
*/
|
|
13
|
-
export declare function clearPolicyCache(): void;
|
|
14
|
-
/**
|
|
15
|
-
* Build the id-aa-signingCertificateV2 attribute value (DER-encoded).
|
|
16
|
-
*
|
|
17
|
-
* This attribute links the signature to the specific certificate used to
|
|
18
|
-
* create it, preventing substitution attacks.
|
|
19
|
-
*
|
|
20
|
-
* ASN.1 structure (RFC 5035):
|
|
21
|
-
*
|
|
22
|
-
* SigningCertificateV2 ::= SEQUENCE {
|
|
23
|
-
* certs SEQUENCE OF ESSCertIDv2
|
|
24
|
-
* }
|
|
25
|
-
*
|
|
26
|
-
* ESSCertIDv2 ::= SEQUENCE {
|
|
27
|
-
* hashAlgorithm AlgorithmIdentifier DEFAULT {algorithm id-sha256},
|
|
28
|
-
* certHash Hash,
|
|
29
|
-
* issuerSerial IssuerSerial OPTIONAL
|
|
30
|
-
* }
|
|
31
|
-
*
|
|
32
|
-
* IssuerSerial ::= SEQUENCE {
|
|
33
|
-
* issuer GeneralNames,
|
|
34
|
-
* serialNumber CertificateSerialNumber
|
|
35
|
-
* }
|
|
36
|
-
*
|
|
37
|
-
* @param certDer - DER-encoded X.509 certificate
|
|
38
|
-
* @returns DER-encoded SigningCertificateV2 value
|
|
39
|
-
*/
|
|
40
|
-
export declare function buildSigningCertificateV2(certDer: Uint8Array): Uint8Array;
|
|
41
|
-
/**
|
|
42
|
-
* Build the id-aa-ets-sigPolicyId attribute value (DER-encoded).
|
|
43
|
-
*
|
|
44
|
-
* Downloads the ICP-Brasil PAdES signature policy and extracts the
|
|
45
|
-
* embedded signPolicyHash to build the attribute.
|
|
46
|
-
*
|
|
47
|
-
* @returns DER-encoded SignaturePolicyIdentifier value
|
|
48
|
-
*/
|
|
49
|
-
export declare function buildSignaturePolicy(): Promise<Uint8Array>;
|
|
50
|
-
/**
|
|
51
|
-
* Attribute OID constants for external use
|
|
52
|
-
*/
|
|
53
|
-
export declare const ICP_BRASIL_OIDS: {
|
|
54
|
-
readonly signingCertificateV2: "1.2.840.113549.1.9.16.2.47";
|
|
55
|
-
readonly signaturePolicy: "1.2.840.113549.1.9.16.2.15";
|
|
56
|
-
};
|
|
57
|
-
export declare class SignaturePolicyError extends Error {
|
|
58
|
-
constructor(message: string);
|
|
59
|
-
}
|
|
60
|
-
//# sourceMappingURL=icp-brasil.d.ts.map
|
package/dist/icp-brasil.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"icp-brasil.d.ts","sourceRoot":"","sources":["../src/icp-brasil.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA8CH;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,CAuCzE;AA2ED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,UAAU,CAAC,CA8BhE;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;;;CAGlB,CAAC;AAMX,qBAAa,oBAAqB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI7B"}
|