Skip to content

k-atusa/hugo-protector

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hugo-protector

Client-side AES-256 protection toolkit for Hugo sites. Encrypt sensitive Markdown/HTML fragments offline, commit only ciphertext, and prompt visitors for a password at runtime.

Features

  • AES-256-GCM encryption with PBKDF2 key derivation (default 310k iterations).
  • Node.js CLI that outputs ready-to-use Hugo shortcodes or front-matter snippets.
  • Hugo shortcode for protecting inline/section content.
  • Full-page lock overlay that requires a password before rendering any content.
  • Front-end runtime (static/hugo-protector/protector.js) that decrypts inside the browser via Web Crypto.

Getting Started

  1. Install dependencies (if you plan to publish the package, otherwise just run via npx):

    npm install
  2. Make sure the front-end script is loaded. In your Hugo layout (e.g., layouts/_default/baseof.html), include:

    <script defer src="{{ "hugo-protector/protector.js" | relURL }}"></script>
  3. (Optional) Add the full-page partial right after your <main> element to render the password overlay when needed:

    {{ partial "protector/full_page.html" . }}

Encrypting Content

Use the CLI to encrypt raw HTML (typically the rendered Markdown fragment). Provide plaintext via file, --text, or stdin. Supply the password via --password-file, --password, or the HUGO_PROTECTOR_PASSWORD environment variable.

# Encrypt a snippet for shortcode usage
hugo-protector encrypt \
  --input snippets/financials.html \
  --password-file .password \
  --mode shortcode

# Encrypt full-page content and copy the front-matter snippet
hugo-protector encrypt \
  --input content/secret-page.rendered.html \
  --password-file .password \
  --mode page

Flags of interest:

Flag Description
-i, --input <file> Read plaintext from file (defaults to stdin).
-t, --text <string> Provide plaintext inline.
-p, --password <value> Pass password directly (use only for testing).
--password-file <file> Read password from file (recommended).
--iterations <num> Override PBKDF2 iterations (default 310000).
`-m, --mode <shortcode page>`
`--format <raw helper>`
`--shortcode-format <html markdown>`
--prompt <text> Adds a prompt attribute to the shortcode helper output.
--button <text> Adds a button attribute to the shortcode helper output.
--hint <text> Adds a hint attribute to the shortcode helper output.

Shortcode Usage (Partial Protection)

Paste the helper output directly in your Markdown:

{{< protector payload="BASE64_PAYLOAD" prompt="Team password" hint="Contact ops" >}}

Parameters:

  • payload (required): base64 payload generated by the CLI.
  • prompt (optional): label displayed above the password input.
  • button (optional): custom unlock button text.
  • hint (optional): small helper text rendered under the form. -- format (optional): html (deprecated) or markdown (default). The runtime renders Markdown when this attribute is present and set to markdown. CLI helper output now defaults to markdown, so no extra flag is needed unless you explicitly want html behavior.

When using the CLI helper output, pass --shortcode-format html to force plain HTML output, or use --prompt, --button, and --hint to localize the unlock form directly from the CLI.

When the page loads, the shortcode renders a password form. On successful decrypt, the placeholder is replaced with the original HTML fragment.

Example encrypting Markdown directly:

npx hugo-protector encrypt \
	--text "enc" \
	--password-file .password \
	--shortcode-format markdown \
	--prompt "team password" \
	--button "open" \
	--hint "announced on Slack"
{{< protector 
	payload="BASE64_PAYLOAD"
	prompt="team password" 
	button="open"
	hint="announced on Slack" 
	format="markdown"
>}}

Full-Page Protection

  1. Encrypt the fully rendered HTML you wish to ship (e.g., run hugo locally and save the .Content output).
  2. Store the payload in your page front matter:
---
title: "Quarterly Strategy"
protector_full_page_payload: "BASE64_PAYLOAD"
protector_full_page_prompt: "Enter the shared secret"
protector_full_page_target: "#main"
---
  1. Ensure {{ partial "protector/full_page.html" . }} is included in the relevant layout (commonly baseof.html or single.html). The partial renders a fullscreen overlay that injects the decrypted HTML into the element referenced by protector_full_page_target (defaults to main).

Security Notes

  • Password strength matters: choose long, unique phrases and share them securely.
  • Increase --iterations if visitors use modern hardware; lower it if decryption feels slow on mobile.
  • The decrypted HTML is inserted straight into the DOM. Only encrypt content you trust, or sanitize on decrypt if needed.
  • The password never leaves the browser; failed attempts simply keep the form visible.

Development

  • bin/hugo-protector.js — CLI entry.
  • src/encryption.js — AES/PBKDF2 helpers.
  • static/hugo-protector/protector.js — browser runtime that powers both shortcodes and full-page locks.
  • layouts/shortcodes/protector.html — shortcode definition.
  • layouts/partials/protector/full_page.html — overlay partial for .Params.protector_full_page_payload.

See docs/ARCHITECTURE.md for a deeper dive into data flow and component boundaries.

About

encrypt your static hugo site

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors