mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-20 11:24:05 -06:00
Add message frontmatter, field. Encrypted the encrypt docs for PoC
This commit is contained in:
parent
2533c5b01a
commit
ff83a93588
@ -2,6 +2,9 @@
|
|||||||
title: "Encrypt"
|
title: "Encrypt"
|
||||||
tags:
|
tags:
|
||||||
- plugin/transformer
|
- plugin/transformer
|
||||||
|
encrypt: true
|
||||||
|
encrypt_message: '^ Password is "quartz"'
|
||||||
|
password: "quartz"
|
||||||
---
|
---
|
||||||
|
|
||||||
This plugin enables content encryption for sensitive pages in your Quartz site. It uses AES encryption with password-based access control, allowing you to protect specific pages or entire folders with passwords.
|
This plugin enables content encryption for sensitive pages in your Quartz site. It uses AES encryption with password-based access control, allowing you to protect specific pages or entire folders with passwords.
|
||||||
@ -63,6 +66,7 @@ Use frontmatter to encrypt individual pages or override folder passwords:
|
|||||||
title: "My Secret Page"
|
title: "My Secret Page"
|
||||||
encrypt: true
|
encrypt: true
|
||||||
password: "page-specific-password"
|
password: "page-specific-password"
|
||||||
|
encrypt_message: "Sorry, this one is only for my eyes,"
|
||||||
---
|
---
|
||||||
This content will be encrypted and require a password to view.
|
This content will be encrypted and require a password to view.
|
||||||
```
|
```
|
||||||
@ -73,6 +77,7 @@ The plugin recognizes these frontmatter fields:
|
|||||||
|
|
||||||
- `encrypt`: Set to `true` to enable encryption for this page
|
- `encrypt`: Set to `true` to enable encryption for this page
|
||||||
- `password`: The password required to decrypt this page
|
- `password`: The password required to decrypt this page
|
||||||
|
- `encrypt_message`: Message to be shown on the unlock page.
|
||||||
|
|
||||||
If a page is in an encrypted folder but has its own `password` field, the page-specific password will be used instead of the folder password.
|
If a page is in an encrypted folder but has its own `password` field, the page-specific password will be used instead of the folder password.
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,11 @@ Quartz supports the following frontmatter:
|
|||||||
- `date`
|
- `date`
|
||||||
- encrypt
|
- encrypt
|
||||||
- `encrypt`
|
- `encrypt`
|
||||||
|
- `encrypted`
|
||||||
|
- encryptMessage
|
||||||
|
- `encrypt_message`
|
||||||
|
- `encryptMessage`
|
||||||
|
- `encrypt-message`
|
||||||
- password
|
- password
|
||||||
- `password`
|
- `password`
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.encryption-notice p {
|
.encryption-notice p {
|
||||||
margin: 0 0 1.5rem 0;
|
|
||||||
color: var(--gray);
|
color: var(--gray);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
@ -151,3 +150,13 @@
|
|||||||
font-size: 16px; /* Prevent zoom on iOS */
|
font-size: 16px; /* Prevent zoom on iOS */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.encrypted-message-footnote {
|
||||||
|
color: var(--gray);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
opacity: 0.8;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
font-style: italic;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -59,7 +59,7 @@ function generateRSSFeed(cfg: GlobalConfiguration, idx: ContentIndexMap, limit?:
|
|||||||
<title>${escapeHTML(content.title)}</title>
|
<title>${escapeHTML(content.title)}</title>
|
||||||
<link>https://${joinSegments(base, encodeURI(slug))}</link>
|
<link>https://${joinSegments(base, encodeURI(slug))}</link>
|
||||||
<guid>https://${joinSegments(base, encodeURI(slug))}</guid>
|
<guid>https://${joinSegments(base, encodeURI(slug))}</guid>
|
||||||
<description><![CDATA[ ${content.encrypted ? content.description : (content.richContent ?? content.description)} ]]></description>
|
<description><![CDATA[ ${content.richContent ?? content.description} ]]></description>
|
||||||
<pubDate>${content.date?.toUTCString()}</pubDate>
|
<pubDate>${content.date?.toUTCString()}</pubDate>
|
||||||
</item>`
|
</item>`
|
||||||
|
|
||||||
@ -111,9 +111,10 @@ export const ContentIndex: QuartzEmitterPlugin<Partial<Options>> = (opts) => {
|
|||||||
links: file.data.links ?? [],
|
links: file.data.links ?? [],
|
||||||
tags: file.data.frontmatter?.tags ?? [],
|
tags: file.data.frontmatter?.tags ?? [],
|
||||||
content: file.data.text ?? "",
|
content: file.data.text ?? "",
|
||||||
richContent: opts?.rssFullHtml
|
richContent:
|
||||||
? escapeHTML(toHtml(tree as Root, { allowDangerousHtml: true }))
|
!file.data.encrypted && opts?.rssFullHtml
|
||||||
: undefined,
|
? escapeHTML(toHtml(tree as Root, { allowDangerousHtml: true }))
|
||||||
|
: undefined,
|
||||||
date: date,
|
date: date,
|
||||||
description: file.data.description ?? "",
|
description: file.data.description ?? "",
|
||||||
encrypted: file.data.encrypted,
|
encrypted: file.data.encrypted,
|
||||||
|
|||||||
@ -30,9 +30,9 @@ export const Description: QuartzTransformerPlugin<Partial<Options>> = (userOpts)
|
|||||||
() => {
|
() => {
|
||||||
return async (tree: HTMLRoot, file) => {
|
return async (tree: HTMLRoot, file) => {
|
||||||
if (file.data?.encrypted) {
|
if (file.data?.encrypted) {
|
||||||
file.data.description = i18n(
|
file.data.description =
|
||||||
ctx.cfg.configuration.locale,
|
file.data.encryptMessage ||
|
||||||
).components.encryption.encryptedDescription
|
i18n(ctx.cfg.configuration.locale).components.encryption.encryptedDescription
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -146,6 +146,10 @@ export const EncryptPlugin: QuartzTransformerPlugin<Partial<Options>> = (userOpt
|
|||||||
}
|
}
|
||||||
|
|
||||||
file.data.encrypted = true
|
file.data.encrypted = true
|
||||||
|
file.data.password = password
|
||||||
|
if (file.data?.frontmatter?.encryptMessage) {
|
||||||
|
file.data.encryptMessage = file.data.frontmatter.encryptMessage as string
|
||||||
|
}
|
||||||
|
|
||||||
if (file.data?.frontmatter?.title) {
|
if (file.data?.frontmatter?.title) {
|
||||||
file.data.frontmatter.title = `🔒 ${file.data.frontmatter.title}`
|
file.data.frontmatter.title = `🔒 ${file.data.frontmatter.title}`
|
||||||
@ -171,6 +175,7 @@ export const EncryptPlugin: QuartzTransformerPlugin<Partial<Options>> = (userOpt
|
|||||||
|
|
||||||
// Encrypt the content
|
// Encrypt the content
|
||||||
const encryptedContent = encryptContent(htmlContent, password, opts)
|
const encryptedContent = encryptContent(htmlContent, password, opts)
|
||||||
|
console.log(file.data)
|
||||||
|
|
||||||
// Create a new tree with encrypted content placeholder
|
// Create a new tree with encrypted content placeholder
|
||||||
const encryptedTree = fromHtml(
|
const encryptedTree = fromHtml(
|
||||||
@ -182,6 +187,7 @@ export const EncryptPlugin: QuartzTransformerPlugin<Partial<Options>> = (userOpt
|
|||||||
<div class="decrypt-form">
|
<div class="decrypt-form">
|
||||||
<input type="password" class="decrypt-password" placeholder="${t.enterPassword}" />
|
<input type="password" class="decrypt-password" placeholder="${t.enterPassword}" />
|
||||||
<button class="decrypt-button">${t.decrypt}</button>
|
<button class="decrypt-button">${t.decrypt}</button>
|
||||||
|
${file.data.encryptMessage ? `<p class="encrypted-message-footnote">${file.data.encryptMessage}</p>` : ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="decrypt-loading">
|
<div class="decrypt-loading">
|
||||||
<div class="loading-spinner"></div>
|
<div class="loading-spinner"></div>
|
||||||
@ -228,5 +234,7 @@ export const EncryptPlugin: QuartzTransformerPlugin<Partial<Options>> = (userOpt
|
|||||||
declare module "vfile" {
|
declare module "vfile" {
|
||||||
interface DataMap {
|
interface DataMap {
|
||||||
encrypted: boolean
|
encrypted: boolean
|
||||||
|
encryptMessage?: string
|
||||||
|
password?: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,6 +118,19 @@ export const FrontMatter: QuartzTransformerPlugin<Partial<Options>> = (userOpts)
|
|||||||
|
|
||||||
if (socialImage) data.socialImage = socialImage
|
if (socialImage) data.socialImage = socialImage
|
||||||
|
|
||||||
|
const encrypted = coalesceAliases(data, ["encrypted", "encrypt"])
|
||||||
|
if (encrypted) data.encrypt = true
|
||||||
|
|
||||||
|
const password = coalesceAliases(data, ["password"])
|
||||||
|
if (password) data.password = password
|
||||||
|
|
||||||
|
const encryptMessage = coalesceAliases(data, [
|
||||||
|
"encryptMessage",
|
||||||
|
"encrypt_message",
|
||||||
|
"encrypt-message",
|
||||||
|
])
|
||||||
|
if (encryptMessage) data.encryptMessage = encryptMessage
|
||||||
|
|
||||||
// Remove duplicate slugs
|
// Remove duplicate slugs
|
||||||
const uniqueSlugs = [...new Set(allSlugs)]
|
const uniqueSlugs = [...new Set(allSlugs)]
|
||||||
allSlugs.splice(0, allSlugs.length, ...uniqueSlugs)
|
allSlugs.splice(0, allSlugs.length, ...uniqueSlugs)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user