feat: Add Digital Signature and Validate Signature tools

New Features:
- Digital Signature tool: Sign PDFs with X.509 certificates (PFX/PEM)
  - Visible and invisible signatures
  - All pages, first page, last page, or custom page selection
  - Dynamic signature height based on text content
  - Custom signature text, image, and styling options

- Validate Signature tool: Verify digital signatures in PDFs
  - Extract and parse PKCS#7 signatures
  - View signer and issuer certificate details
  - Check certificate validity and expiry
  - Optional custom X.509 certificate for trust verification
  - Full/partial coverage detection

Infrastructure:
- Added Cloudflare Worker CORS proxy for certificate chain fetching
- Updated README with new tools and proxy deployment instructions

Documentation:
- Added Digital Signature and Validate Signature to README tools table
- Added CORS proxy deployment guide for self-hosters
This commit is contained in:
abdullahalam123
2026-01-04 19:08:50 +05:30
parent 94504d4b75
commit 05110c7f6a
20 changed files with 1703 additions and 24 deletions

View File

@@ -6,7 +6,8 @@
*/
import { WorkerBrowserConverter } from '@matbee/libreoffice-converter/browser';
import { getWasmBaseUrl, getWasmFallbackUrl, isCdnEnabled } from '../config/wasm-cdn-config.js';
const LIBREOFFICE_LOCAL_PATH = import.meta.env.BASE_URL + 'libreoffice-wasm/';
export interface LoadProgress {
phase: 'loading' | 'initializing' | 'converting' | 'complete' | 'ready';
@@ -24,12 +25,9 @@ export class LibreOfficeConverter {
private initialized = false;
private initializing = false;
private basePath: string;
private localPath: string;
constructor(basePath?: string) {
// Use CDN if available, otherwise use provided basePath or default local path
this.basePath = basePath || getWasmBaseUrl('libreoffice');
this.localPath = getWasmFallbackUrl('libreoffice');
this.basePath = basePath || LIBREOFFICE_LOCAL_PATH;
}
async initialize(onProgress?: ProgressCallback): Promise<void> {
@@ -49,14 +47,12 @@ export class LibreOfficeConverter {
try {
progressCallback?.({ phase: 'loading', percent: 0, message: 'Loading conversion engine...' });
const workerPath = isCdnEnabled() ? this.localPath : this.basePath;
this.converter = new WorkerBrowserConverter({
sofficeJs: `${this.basePath}soffice.js`,
sofficeWasm: `${this.basePath}soffice.wasm.gz`,
sofficeData: `${this.basePath}soffice.data.gz`,
sofficeWorkerJs: `${workerPath}soffice.worker.js`,
browserWorkerJs: `${workerPath}browser.worker.global.js`,
sofficeWorkerJs: `${this.basePath}soffice.worker.js`,
browserWorkerJs: `${this.basePath}browser.worker.global.js`,
verbose: false,
onProgress: (info: { phase: string; percent: number; message: string }) => {
if (progressCallback && !this.initialized) {