Files
vue-journal-layer/app/utils/htmlGate.ts
Jakub Zych 6f6792f51c feat: scaffold Journal layer with configurable post route and git-install check
- journal module registers the Journal pages at journal.routes paths
- typed anonymous-GET client, html gate, SSR x-forwarded-for forwarding
- fixture API, built-server SSR smoke and git-tag install check
2026-10-09 17:31:45 +02:00

24 lines
1.1 KiB
TypeScript

// HTML gate for every v-html sink (post body, category content, author bio).
// The three patterns are the verbatim regex sources of the Journal plugin's
// FormatHTML / CheckHTML gate (classes/format_html.go), with the i flag for
// Go's (?i). Imported content bypasses the Go gate, so the layer checks again.
export const UNSAFE_TAG = /<(?:script|iframe|object|embed)\b/i
export const EVENT_HANDLER = /\son[a-z]+\s*=/i
export const DANGEROUS_URL = /(?:javascript|vbscript|data):/i
/** True when `html` matches none of the three Journal patterns. */
export function isSafeJournalHtml(html: string | null | undefined): boolean {
if (!html) return true
return !(UNSAFE_TAG.test(html) || EVENT_HANDLER.test(html) || DANGEROUS_URL.test(html))
}
/**
* Gate result for a v-html sink: `html` is the input when safe and "" when
* not, so the unsafe value never reaches the DOM. Null input is safe and "".
*/
export function gateJournalHtml(html: string | null | undefined): { safe: boolean; html: string } {
if (!html) return { safe: true, html: '' }
return isSafeJournalHtml(html) ? { safe: true, html } : { safe: false, html: '' }
}