Skip to content

Modernize v1.0.0 Release#11

Merged
tgies merged 19 commits intomasterfrom
modernize-v1
Jan 19, 2026
Merged

Modernize v1.0.0 Release#11
tgies merged 19 commits intomasterfrom
modernize-v1

Conversation

@tgies
Copy link
Copy Markdown
Owner

@tgies tgies commented Jan 19, 2026

Summary

This PR completes the comprehensive modernization of client-certificate-auth for the v1.0.0 release.

New Features

  • Reverse proxy certificate passthrough via X-Client-Cert header
  • Attach parsed client certificate to req.clientCertificate
  • Authorization helper utilities (requireClientCert, requireAuthorizedCert, requireAnyAuthorizedCert)
  • Granular authorization feedback with custom error messages
  • Certificate chain access via includeChain option
  • Fixed type augmentation export visibility
  • CJS wrapper validation for unsupported options

Security Improvements

  • Removed redirectInsecure (anti-pattern)
  • Added verifyHeader/verifyValue for secure proxy header validation

Infrastructure

  • Jest test runner (migrated from Mocha)
  • 100% code coverage enforcement
  • NPM publish workflow with provenance
  • Codecov integration
  • SECURITY.md and CONTRIBUTING.md

Documentation

  • Comprehensive README with usage examples
  • User login implementation guide
  • Full CHANGELOG

tgies added 19 commits January 12, 2026 23:55
- Migrate to ES modules with CommonJS compatibility wrapper
- Add TypeScript declarations (.d.ts/.d.cts)
- Replace Travis CI with GitHub Actions
- Update to modern Node.js 18+ with c8 coverage
- Add ESLint with flat config
- Add integration tests for real mTLS connections
- Update README and add CHANGELOG
- Add .gitignore and FUNDING.yml
- Replace Mocha with Jest for testing
- Update package.json scripts for Jest with ESM support
- Add jest.config.js with test patterns and timeout
- Remove .mocharc.json
- Update eslint.config.js to use Jest globals
- Update .npmignore for Jest config
- Add test for cached module branch (100% branch coverage)
Complete implementation of certificate extraction from proxy headers:

Presets:
- aws-alb: X-Amzn-Mtls-Clientcert (URL-encoded PEM)
- envoy: X-Forwarded-Client-Cert (XFCC format)
- cloudflare: Cf-Client-Cert-Der-Base64 (Base64 DER)
- traefik: X-Forwarded-Tls-Client-Cert (Base64 DER with chain)

Features:
- certificateSource option for preset selection
- certificateHeader/headerEncoding for custom headers
- fallbackToSocket option for hybrid deployments
- Full cert chain support via issuerCertificate linking

Testing:
- 93 unit/integration tests with 100% coverage
- 13 E2E tests with real nginx, Envoy, Traefik proxies
- Docker Compose test infrastructure

Documentation:
- Updated README with proxy configuration examples
- TypeScript declarations for all new APIs
- Security considerations documented
WORK-002: After successful certificate extraction, the middleware now
attaches the certificate to req.clientCertificate for downstream handler
access. This is now the default behavior - no opt-in option needed.

Changes:
- Middleware attaches cert to req.clientCertificate before auth callback
- TypeScript declarations updated (both ESM and CJS)
- Fix: CJS declarations now include WORK-001 reverse-proxy options
  (certificateSource, certificateHeader, headerEncoding, fallbackToSocket)
- 6 new tests verifying attachment in all scenarios
- README updated with usage examples

The certificate is attached before the authorization callback runs, so
it's available even if authorization fails (useful for error logging).
Adds a new helpers module with pre-built validation callbacks for common
mTLS authorization patterns:

- allowCN: match by Common Name
- allowFingerprints: match by certificate fingerprint
- allowIssuer: match by issuer fields (partial)
- allowSubject: match by subject fields (partial)
- allowOU: match by Organizational Unit
- allowOrganization: match by Organization
- allowSerial: match by serial number
- allowSAN: match by Subject Alternative Name
- allowEmail: match by email (SAN or subject)
- allOf: AND combinator
- anyOf: OR combinator

Includes:
- Full TypeScript declarations
- 163 unit/integration tests with 100% coverage
- 18 E2E tests with real nginx proxy
- README documentation with examples

Closes WORK-003
WORK-004: Thrown errors from authorization callbacks now get status = 401
if not already set, enabling granular feedback to Express error handlers.

Changes:
- ESM: Added status = 401 assignment in both sync/async catch handlers
- CJS: Added req.clientCertificate decoration (was missing from WORK-002)
- CJS: Added status = 401 assignment for thrown errors
- Added 8 new tests (4 ESM, 4 CJS) for error status behavior
- README: Added 'Custom Error Messages' section with examples
WORK-005: Full Certificate Chain Access

Changes:
- Add includeChain option (default: false) to include issuerCertificate chain
- Normalize behavior: strip issuerCertificate from header-parsed certs unless enabled
- Pass includeChain flag to getPeerCertificate() for socket-based extraction
- Update TypeScript declarations with DetailedPeerCertificate support
- Add 6 unit tests covering socket and header-based chain handling
- Update README with new option documentation and usage examples
WORK-013: Remove Host Header Injection Vulnerability
- Removed redirectInsecure option entirely (inherently insecure)
- Removed from ESM, CJS, TypeScript definitions
- Removed associated tests and README documentation

WORK-014: Add Verification Header Support
- Added verifyHeader/verifyValue options for defense-in-depth
- Both options must be specified together when used
- Returns 401 if verification header missing or value doesn't match
- Added 4 unit tests and 2 E2E tests
- Updated README with nginx configuration example

BREAKING CHANGE: redirectInsecure option has been removed
Show how to map client certificates to user accounts using
fingerprint, email, or CN-based database lookups. Includes
example for attaching user object to req for downstream routes.
WORK-008: Add global.d.ts reference to type declarations
WORK-015: Add runtime validation for unsupported CJS options

Changes:
- Added /// <reference path="./global.d.ts" /> to both .d.ts and .d.cts
- Simplified .d.cts ClientCertificateAuthOptions to only include includeChain
- Added UNSUPPORTED_OPTIONS validation in CJS wrapper that throws descriptive error
- Added 9 tests for CJS unsupported options error cases
- Maintains 100% test coverage (184 tests)
@codecov
Copy link
Copy Markdown

codecov bot commented Jan 19, 2026

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

@tgies tgies merged commit ddbd4ab into master Jan 19, 2026
16 of 17 checks passed
@tgies tgies deleted the modernize-v1 branch January 19, 2026 07:17
tgies added a commit that referenced this pull request Jan 26, 2026
- Pin codecov/codecov-action to commit SHA (v5.5.2)
- Pin softprops/action-gh-release to commit SHA (v2.5.0)
- Add explicit permissions block (contents: read) to ci.yml
- Add explicit permissions block (contents: read) to e2e.yml
- Add explicit permissions block (contents: read) to mutation.yml

Fixes CodeQL alerts #1-6, #11, #12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant