fix(shared-help): harden help system with XSS protection, i18n, type safety, and reference implementation

- Add HTML sanitization via isomorphic-dompurify in parser layer to prevent XSS
- Replace all hardcoded English strings with translations (FAQSection, KeyboardShortcuts, ChangelogEntry/Section)
- Remove unsafe `as` type casting in loader.ts, use Zod-inferred generics instead
- Add error logging in content loader (replaces silent catch blocks)
- Fix HelpSearch blur handling (mousedown+preventDefault instead of setTimeout hack)
- Add ARIA attributes to HelpSearch for accessibility
- Derive FAQ categories from items instead of hardcoding all 6
- Fix null-safety in GettingStartedGuide.svelte
- Fix unused appId variable in HelpPage.svelte, add scroll-reset on tab switch
- Rebuild Contacts help page as reference implementation using shared HelpPage component
- Add README with quick-start guide, props docs, and translations template

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-24 22:38:46 +01:00
parent 8356ac634a
commit 42dd7d2a7a
18 changed files with 845 additions and 801 deletions

View file

@ -18,6 +18,7 @@ import type {
SearchIndexConfig,
} from '@manacore/shared-help-types';
import { generateExcerpt, stripHtml } from './parser.js';
import { sanitizeHtml } from './sanitize.js';
const DEFAULT_CONFIG: SearchIndexConfig = {
titleWeight: 2,
@ -135,8 +136,10 @@ function findOriginalItem(
*/
function highlightMatch(text: string, query: string): string {
if (!query.trim()) return text;
// Sanitize text first, then apply highlighting
const safeText = sanitizeHtml(text);
const regex = new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
return text.replace(regex, '<mark>$1</mark>');
return safeText.replace(regex, '<mark>$1</mark>');
}
/**