Skip to content

Conversation

@madjin
Copy link
Contributor

@madjin madjin commented Dec 16, 2025

Summary

  • Adds a generator script that creates print-optimized HTML checklists from SFC certification MDX files
  • Adds a Print button to certification pages (next to Import/Export) that opens the printable version
  • 3-column CSS layout with smart section chunking for optimal print layout

Features

  • Print Button: Each SFC cert page now has a Print button linking to /printable/{cert-name}.html
  • Print-Optimized HTML: Standalone pages with org/owner/date fields, checkboxes, and notes sections
  • Auto-Generated: Runs during build, outputs to docs/public/printable/

Files Changed

  • utils/generate-printable-checklists.js - New generator script
  • components/cert/CertList.tsx - Print button added
  • components/cert/control.css - Print button styling
  • package.json - Build script integration
  • .gitignore - Ignore generated files

Test plan

  • Run pnpm run docs:dev and verify Print button appears on cert pages
  • Click Print button and verify printable HTML loads
  • Test print/PDF export from browser
  • Run pnpm run docs:build and verify files in docs/dist/printable/

🤖 Generated with Claude Code

Preview

Screenshot from 2025-12-16 01-48-17 Screenshot from 2025-12-16 01-25-14

madjin and others added 2 commits December 16, 2025 01:35
- New utils/generate-printable-checklists.js script that reads cert MDX files
  and generates print-optimized HTML checklists
- 3-column CSS layout with smart section chunking (splits at midpoint if >6 controls)
- Runs as postdocs:build hook, outputs to docs/dist/printable/
- Includes print button, org/owner/date fields, and notes area per section

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Print button to CertList component linking to printable HTML
- Style print button to match existing Import/Export buttons
- Fix output path to docs/public/printable/ for vocs compatibility
- Move generate-printables before vocs build for production support
- Add docs/public/printable/ to gitignore (generated files)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Dec 16, 2025

@madjin is attempting to deploy a commit to the Security Alliance Team on Vercel.

A member of the Team first needs to authorize it.

- Escape title/subtitle for XSS prevention
- Sanitize certName for safe URL/filename use
- Filter invalid control objects
- Coerce text input to String in escapeHtml

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@smagdali
Copy link
Collaborator

This is cool (and the output looks great), but why deploy as a separate doc and button, rather than a standard print style sheet that is used when someone chooses Print in the browser?

Generally, it's considered not-great-practice to replicate browser furniture.

Does it trigger if I hit cmd-p ?

(maybe it does - I couldn't see from my skim of the code - dismiss at will).

@madjin
Copy link
Contributor Author

madjin commented Dec 16, 2025

This is cool (and the output looks great), but why deploy as a separate doc and button, rather than a standard print style sheet that is used when someone chooses Print in the browser?

Generally, it's considered not-great-practice to replicate browser furniture.

Does it trigger if I hit cmd-p ?

(maybe it does - I couldn't see from my skim of the code - dismiss at will).

image

not replicating browser furniture on the main page, moreso providing a link to a purpose-built printable form with fields for Org/Owner/Date, dense layout. Can print via button or cmd/ctrl-p on the new page

@smagdali
Copy link
Collaborator

It's a nit, but (more) correct behaviour would be to deploy that style sheet if someone prints the main page. https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Media_queries/Printing
https://wblinks.com/notes/always-include-a-print-stylesheet/

Per reviewer feedback, adds @media print styles so cmd-p on main
pages produces clean output:
- Hides nav, sidebar, banner, footer, action buttons
- Full-width content with print margins
- White background, black text
- Shows URLs after external links
- Prevents awkward page breaks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@madjin
Copy link
Contributor Author

madjin commented Dec 16, 2025

Added print stylesheet so now ctrl/cmd-p on main page produces cleaner output. It's ~4x more pages (single-column web layout) vs the dedicated printable which is optimized as a dense 3-column paper form.

Here's how modified stylesheet looks, 12 pages vs 7 pages (after):

image

The dense html form is 2 pages. Both options now work ^^

image

- Hide additional vocs chrome elements (gutterTop, curtains, search)
- Hide cert interactive elements (progress bars, toggles, inputs)
- Force sections to expand when printing
- Clean control card styling with subtle separators
- Prevent page breaks inside control cards
- Reduce padding for better content density

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@DicksonWu654
Copy link
Collaborator

DicksonWu654 commented Jan 4, 2026

Hey @madjin super sorry for the delay! The printable version looks amazing! Thank you so much!

But I found 1 bug: if you have frameworks on darkmode, the printable versions are unreadable 😅

image

I'm gonna suggest some fixes in the pr review

Copy link
Collaborator

@DicksonWu654 DicksonWu654 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fixes to the black background for darkmode print

madjin and others added 12 commits January 8, 2026 12:49
Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
Adds the first and most critical review suggestion that was missed:
force color-scheme: light only !important on :root for print media.

This ensures browsers render print preview in light mode regardless
of user's system theme preference.

Co-authored-by: Dickson Wu <33645481+DicksonWu654@users.noreply.github.com>
@DicksonWu654 DicksonWu654 self-requested a review January 9, 2026 05:07
Copy link
Collaborator

@DicksonWu654 DicksonWu654 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@vercel
Copy link

vercel bot commented Jan 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
frameworks Ready Ready Preview, Comment Jan 12, 2026 10:36am

@scode2277 scode2277 added the enhancement Updates that improve or refine existing features, user experience, or system performance. label Jan 12, 2026
@madjin
Copy link
Contributor Author

madjin commented Jan 22, 2026

Security Review: PR #320 - Printable Checklists

Overview

Quick security review of the printable checklist generator for potential hardening.


Findings

1. Path Sanitization Gap (Medium)

File: utils/generate-printable-checklists.js:370

The sanitizeCertName() function exists and is used for URL generation, but not for the output file path:

const certName = file.replace('.mdx', '');  // unsanitized                                                                     
const outputPath = path.join(OUTPUT_DIR, `${certName}.html`);                                                                  

Fix: Apply existing sanitizer to both uses:

const certName = sanitizeCertName(file.replace('.mdx', ''));                                                                   

2. Input Validation (Low)

Control properties from YAML are escaped but not type-checked. Malformed frontmatter could cause unexpected behavior.

Optional hardening:

if (typeof c.title !== 'string') continue;                                                                                     

What's Already Good

  • HTML escaping applied to all user content via escapeHtml()
  • Input files filtered to sfc-*.mdx pattern
  • Output directory gitignored
  • Link uses rel="noopener noreferrer"

Recommendation

Apply the one-line path sanitization fix. Everything else is defense-in-depth and optional.

@madjin
Copy link
Contributor Author

madjin commented Jan 22, 2026

Option 2: Consider Separating from Dev Build

Currently generate-printables runs on every docs:dev. Consider:

"docs:dev": "... && vocs dev", // no printables
"docs:build": "... && pnpm run generate-printables && vocs build", // build-only

Why? Reduces attack surface during normal dev - the generator only executes when deploying. Devs can
still run pnpm run generate-printables manually when needed.

Can also make it a CI-only thing + manual command only for even more protection

- Apply sanitizeCertName() to output file path (not just URL)
- Add type validation for control.title from YAML frontmatter
- Move generate-printables from docs:dev to docs:build only

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@madjin
Copy link
Contributor Author

madjin commented Jan 28, 2026

Implemented the security hardening suggestions:

  1. Path sanitization - sanitizeCertName() now applied to output file path, with validation to skip malformed filenames
  2. Input validation - Added typeof c.title === 'string' check for YAML control properties
  3. Separated from dev - generate-printables removed from docs:dev, runs only on docs:build

Devs can still run pnpm run generate-printables manually when needed during local development.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Updates that improve or refine existing features, user experience, or system performance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants