Implement shared HTML sanitization configuration

**Backend Changes:**
- Add html-sanitization-config.json with allowedTags, allowedAttributes, and allowedCssProperties
- Create HtmlSanitizationConfigDto for configuration data transfer
- Update HtmlSanitizationService to load configuration from JSON file with fallback
- Add HtmlSanitizationController with public API endpoint at /api/config/html-sanitization
- Update SecurityConfig to allow public access to /api/config/** endpoints

**Frontend Changes:**
- Add configApi.getHtmlSanitizationConfig() to fetch backend configuration
- Create sanitization.ts utility with sanitizeHtml() and sanitizeHtmlSync() functions
- Update story reading page to use shared sanitization configuration
- Add preloadSanitizationConfig() for early configuration loading
- Handle TrustedHTML type conversion and DOMPurify config compatibility

**Benefits:**
- Consistent HTML sanitization rules between frontend and backend
- Centralized configuration in JSON file for easy maintenance
- Automatic fallback to safe defaults if configuration loading fails
- API-driven approach allows runtime configuration updates
- Maintains security while providing flexibility for content formatting

Resolves HTML sanitization inconsistencies and provides foundation for configurable content safety rules.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Stefan Hardegger
2025-07-23 16:18:03 +02:00
parent f2001e0d0c
commit 5a48ebcfeb
4 changed files with 194 additions and 5 deletions

View File

@@ -273,6 +273,20 @@ export const searchApi = {
},
};
// Configuration endpoints
export const configApi = {
getHtmlSanitizationConfig: async (): Promise<{
allowedTags: string[];
allowedAttributes: Record<string, string[]>;
allowedCssProperties: string[];
removedAttributes: Record<string, string[]>;
description: string;
}> => {
const response = await api.get('/config/html-sanitization');
return response.data;
},
};
// Image utility
export const getImageUrl = (path: string): string => {
if (!path) return '';