VerifyKitv0.5.4

Migration Guide

This guide covers breaking changes, deprecated APIs, and upgrade paths between VerifyKit SDK versions.


Deprecated APIs

The following APIs in @trexolab/verifykit-core are retained for backward compatibility but should no longer be used in new code.

computeUnsignedFields(signatures, detectedFields?)

Status: Stub — always returns an empty array.

The WASM engine does not expose unsigned field detection through this function. Unsigned signature fields are now reported directly in the VerificationResult when present.

Migration: Remove calls to computeUnsignedFields. If you need to detect unsigned form fields, inspect the VerificationResult returned by verifyPdf() or verifier.verify().

getTrustStore()

Status: Stub — returns an object with empty arrays.

Trust store contents are managed internally by the WASM engine and are no longer exposed to JavaScript at runtime.

Migration: Remove calls to getTrustStore(). To configure the trust store, use setTrustStoreConfig() or pass a trustStore config to createVerifier().

ensureCryptoEngine()

Status: No-op.

The Rust/WASM engine ships its own cryptographic implementation and does not depend on the Web Crypto API. This function existed for the legacy JavaScript engine and now does nothing.

Migration: Remove calls to ensureCryptoEngine(). No replacement is needed.


Version History

v0.5.2 to v0.5.3

Release: Adobe-parity improvements + configurable zoom + certificate chain export

Two small visible behavior changes plus a lot of additive API. No required code changes; most integrators can drop-in upgrade.

Behavior changes (may require attention)

  1. SHA-1 signatures now default to valid. Previously, any signature whose only issue was a SHA-1 digest produced overallStatus: 'warning'. As of v0.5.3 the default mirrors Adobe Reader: SHA-1 signatures pass the algorithm check (and SignatureCheckResult.algorithmName is set to "SHA-1" so UIs can still disclose the algorithm). If your app routed the old warning into a specific UI state or metric, either update that logic or restore the strict policy:

    ts
    import { createVerifier } from '@trexolab/verifykit-core'
    const verifier = await createVerifier({ algorithmPolicy: { sha1: 'warn' } })
    // — or globally —
    import { setAlgorithmPolicy } from '@trexolab/verifykit-core'
    await setAlgorithmPolicy({ sha1: 'warn' })

    MD5 / MD2 / MD4 remain hardcoded Invalid — not configurable.

  2. Viewer zoom range is now 25 %–1000 % (was 40 %–500 %). Matches pdf.js and lets users inspect fine detail in signature stamps / seals. The zoom dropdown filters to the configured range, so no UI breaks. Restore the old range with:

    tsx
    import { defaultLayoutPlugin } from '@trexolab/verifykit-react'
    const layout = defaultLayoutPlugin({ zoom: { minScale: 0.4, maxScale: 5 } })

    Vanilla: VerifyKit.create(el, { zoom: { minScale: 0.4, maxScale: 5 } }).

New features

  • Legacy adbe.pkcs7.sha1 signatures now verify (previously produced false "document modified" INVALID on PDF 1.3 signatures with no signedAttrs). No migration needed — you'll just see more PDFs verify correctly.
  • Certificate chain export from the Signature Properties dialog's Certificates tab (Export Chain ▾ → PEM / PKCS#7 / ZIP). Also exposed programmatically: new core helper buildCertChainPkcs7 and new React helpers exportCertChainAsPem / exportCertChainAsPkcs7 / exportCertChainAsZip.
  • CertificateInfo.rawDer (Uint8Array) — raw DER bytes now exposed on every CertificateInfo. Never read by the verification pipeline. Per-cert PEM / DER buttons in CertificateViewer.DetailPanel previously rendered only if you populated this field; they now render automatically.
  • AlgorithmPolicy + setAlgorithmPolicy / resetAlgorithmPolicy runtime API — see above.
  • SignatureCheckResult.algorithmName — optional field on every check, populated by the algorithm-strength check so UIs can display the algorithm regardless of overall status.
  • ZoomPluginOptionszoomPlugin(), defaultLayoutPlugin({ zoom }), and vanilla VerifyKit.create({ zoom }) all accept { minScale?, maxScale?, step? }.
  • Docs-site: new /faq route + IndexNow protocol + richer JSON-LD schemas. Does not affect SDK consumers.

Repository layout (affects contributors only)

  • Root package renamed verifykitverifykit-monorepo (private, never published).
  • apps/apps/demo/ — conventional monorepo layout. package.json workspaces glob is now "apps/*". Scripts (pack-registry.mjs, next.config.ts) and docs updated.
  • PM2 process renamed verifykitverifykit-demo; npm run pm2:demo is now idempotent.
  • [build:demo] script typo fixed (was unusable with the literal brackets in the key).

Upgrade path: npm install + rebuild. Review the two behavior changes above; apply the opt-out snippets if your app depends on the previous behavior.

v0.4.6 to v0.5.0

Release: Full codebase audit, type safety, and Rust/WASM cleanup

This is a non-breaking quality release. No API changes, no new exports, no removed exports. Drop-in upgrade from v0.4.x.

Key changes:

  • Full TypeScript audit -- resolved all type errors and unused variables across all packages.
  • Rust/WASM engine cleanup -- zero clippy warnings, idiomatic Rust patterns, removed dead functions and stale constants.
  • Plugin-revocation type safety -- fixed type mismatches in handler functions.
  • ESLint configuration overhaul -- unified linting across the monorepo.
  • Fresh production builds verified clean -- all four packages build without warnings.

Upgrade path: Drop-in replacement. Run npm install and rebuild. No code changes required.

v0.4.0 to v0.4.5

Release: Display status fix, Adobe Reader parity improvements, PAdES tab, document timestamp indicators

Key changes:

  • padesLevel is now optional -- PdfSignature.padesLevel has changed from PAdESLevel to PAdESLevel | null. For non-ETSI signatures (e.g., adbe.pkcs7.detached), padesLevel is null. ETSI signatures (ETSI.CAdES.detached, ETSI.RFC3161) continue to report their PAdES conformance level.

  • attempted field on SignatureCheckResult -- A new optional attempted?: boolean field distinguishes between checks that were actively tried (e.g., online revocation request) and checks that were never attempted (e.g., revocation without the plugin). This enables accurate Adobe Reader parity in getDisplayStatus().

  • getDisplayStatus() Adobe Reader parity changes -- The display status logic now considers the attempted field. Revocation checks that were actively attempted but returned unknown cause the display status to be "unknown", while checks that were never attempted (offline) do not penalize the signature. This matches Adobe Reader DC behavior: offline = valid, online + failed = unknown.

  • PAdES tab in signature properties -- The <SignaturePropertiesModal> now includes a PAdES tab that shows the detected conformance level and related details for ETSI signatures.

  • Document Timestamp visual indicators -- Document timestamps (ETSI.RFC3161 sub-filter) are now visually distinguished from regular signatures in the viewer.

Upgrade path:

  1. If your code reads sig.padesLevel, add a null check:

    ts
    // Before
    console.log(`PAdES: ${sig.padesLevel}`) // may be null now
     
    // After
    if (sig.padesLevel) {
      console.log(`PAdES: ${sig.padesLevel}`)
    } else {
      console.log('Standard PKCS#7 signature (no PAdES level)')
    }
  2. If you check revocationCheck.status for UI display, consider using the new attempted field to differentiate between "not checked" and "checked but unknown."

  3. No breaking changes to the React component API. The PAdES tab and document timestamp indicators are added automatically.

v0.3.2 to v0.4.0

Release: Flicker-free appearance swap, single-render VerificationFloater

Key changes:

  • Flicker-free appearance swap — The viewer now swaps between normal and signature appearance streams without visual flicker. Previously, switching appearances could cause a brief blank frame.
  • Single-render VerificationFloater — The VerificationFloater component now renders in a single pass instead of mounting, measuring, and re-rendering. This eliminates layout shift when the floater appears.

Upgrade path: Drop-in replacement. No API changes.

v0.3.1 to v0.3.2

Release: Embed VerificationFloater, smart context menu, live demo, polyfill fix

Key changes:

  • Embedded VerificationFloater — The verification status floater is now embedded directly in the viewer rather than rendered as a portal. This simplifies integration and avoids z-index conflicts.
  • Smart context menu — Right-clicking a signature field now shows a context menu with signature details, certificate info, and verification status.
  • Live demo — The documentation site gained an interactive demo page at /demo.
  • Polyfill fix — Fixed a compatibility issue with the structuredClone polyfill in older browsers and Node.js environments.

Upgrade path: Drop-in replacement. No API changes.

Pre-v0.3.1 to v0.3.1+

This was the most significant architectural change in the SDK's history.

WASM Base64 Embedding

Before v0.3.1, the WASM binary (verifykit_core_wasm_bg.wasm) was shipped as a separate file. You needed bundler plugins to handle it:

js
// vite.config.ts (no longer needed)
import wasm from 'vite-plugin-wasm'
export default { plugins: [wasm()] }
js
// webpack.config.js (no longer needed)
module.exports = {
  experiments: { asyncWebAssembly: true },
}

Since v0.3.1, the WASM binary is base64-embedded directly into the JavaScript bundle. No external .wasm file needs to be served, and no bundler configuration is required. This works out of the box in Vite, webpack, Next.js, Node.js, Deno, and Bun.

Migration:

  1. Remove vite-plugin-wasm or any WASM-related bundler plugins.
  2. Remove webpack asyncWebAssembly experiment configuration.
  3. Remove any static file serving rules for .wasm files.
  4. Update to @trexolab/verifykit-core >= 0.3.1.

If you still need to load the WASM binary from a custom location (e.g., a CDN), you can use setWasmUrl():

ts
import { setWasmUrl } from '@trexolab/verifykit-core'
 
setWasmUrl('/custom/path/verifykit_core_wasm_bg.wasm')

Viewer Migration

Legacy PdfViewer vs. New Viewer / CoreViewer

The SDK originally shipped a monolithic PdfViewer component that bundled all viewer features (toolbar, zoom, search, sidebar, print) into a single component. Starting with the plugin-based architecture, the SDK introduced two new components:

ComponentPackagePurpose
CoreViewer@trexolab/verifykit-reactHeadless viewer — renders PDF pages with no built-in UI. All features are added via plugins.
Viewer@trexolab/verifykit-reactPre-configured viewer — wraps CoreViewer with the defaultLayoutPlugin that includes toolbar, zoom, search, page navigation, print, and sidebar.
PdfViewer@trexolab/verifykit-reactLegacy — kept for backward compatibility. Internally wraps Viewer with the same default configuration.

Migration from PdfViewer to Viewer:

tsx
// Before
import { PdfViewer } from '@trexolab/verifykit-react'
 
<PdfViewer fileUrl="/doc.pdf" />
 
// After
import { Viewer, VerifyKitProvider } from '@trexolab/verifykit-react'
 
<VerifyKitProvider>
  <Viewer fileUrl="/doc.pdf" />
</VerifyKitProvider>

The Viewer component requires a VerifyKitProvider ancestor. The provider initializes the WASM engine, manages verification state, and provides the context that plugins use.

Plugin Architecture Migration

The monolithic PdfViewer included all features by default with no way to remove or customize individual features. The plugin architecture lets you compose only what you need:

tsx
import {
  CoreViewer,
  VerifyKitProvider,
  toolbarPlugin,
  zoomPlugin,
  searchPlugin,
} from '@trexolab/verifykit-react'
 
// Only include zoom and search — no toolbar, no print, no sidebar
const plugins = [zoomPlugin(), searchPlugin()]
 
function App() {
  return (
    <VerifyKitProvider>
      <CoreViewer fileUrl="/doc.pdf" plugins={plugins} />
    </VerifyKitProvider>
  )
}

The defaultLayoutPlugin() is a meta-plugin that composes the standard set of plugins. Use it when you want the full default experience:

tsx
import {
  CoreViewer,
  VerifyKitProvider,
  defaultLayoutPlugin,
} from '@trexolab/verifykit-react'
 
const plugins = [defaultLayoutPlugin()]
 
function App() {
  return (
    <VerifyKitProvider>
      <CoreViewer fileUrl="/doc.pdf" plugins={plugins} />
    </VerifyKitProvider>
  )
}

This is equivalent to using the Viewer component, which applies defaultLayoutPlugin automatically.


Need Help?

If you encounter issues while upgrading, check the Troubleshooting guide or open an issue on the GitHub repository.