UNPKG

@dollhousemcp/mcp-server

Version:

DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.

216 lines 8.81 kB
/** * Template element class implementing IElement interface. * Represents reusable content structures with variable substitution and dynamic content. * * SECURITY FIXES IMPLEMENTED (Following PR #319 patterns): * 1. CRITICAL: Template injection prevention - no eval() or Function() constructor * 2. CRITICAL: Path traversal prevention for template includes * 3. HIGH: Input validation and sanitization for all template variables * 4. MEDIUM: Memory limits to prevent resource exhaustion (100KB templates, 100 variables) * 5. MEDIUM: Audit logging for all security operations via SecurityMonitor * 6. MEDIUM: Unicode normalization to prevent homograph attacks */ import { BaseElement } from '../BaseElement.js'; import { IElement, IElementMetadata, ElementValidationResult } from '../../types/elements/index.js'; import { ElementType } from '../../portfolio/types.js'; import { MetadataService } from '../../services/MetadataService.js'; export interface TemplateMetadata extends IElementMetadata { type?: ElementType.TEMPLATE; category?: string; output_format?: string; variables?: TemplateVariable[]; includes?: string[]; tags?: string[]; usage_count?: number; last_used?: string; examples?: TemplateExample[]; /** * Action verbs that trigger this template (e.g., "create", "generate", "draft") * Used by Enhanced Capability Index for intelligent template suggestions * @since v1.9.10 */ triggers?: string[]; } export interface TemplateVariable { name: string; type: 'string' | 'number' | 'boolean' | 'date' | 'array' | 'object'; description?: string; required?: boolean; default?: unknown; validation?: string; options?: string[]; format?: string; } export interface TemplateExample { title: string; description?: string; variables: Record<string, unknown>; output?: string; } /** Parsed result of a section-format template (issue #705). */ export interface TemplateSections { /** True when the content contains at least one bare section tag. */ isSectionMode: boolean; /** Content of the <template> block — the only section that receives variable substitution. */ templateSection: string; /** Raw content of the <style> block — passed through without variable substitution. */ styleSection: string; /** Raw content of the <script> block — passed through without variable substitution. */ scriptSection: string; } export declare class Template extends BaseElement implements IElement { metadata: TemplateMetadata; private compiledTemplate?; private parsedSections?; private readonly MAX_TEMPLATE_SIZE; private static readonly MAX_VARIABLE_COUNT; private readonly MAX_INCLUDE_DEPTH; private readonly MAX_STRING_LENGTH; constructor(metadata: Partial<TemplateMetadata>, content: string | undefined, metadataService: MetadataService); /** * Validate include paths to prevent directory traversal * SECURITY FIX #2: Prevents accessing files outside template directory */ private isValidIncludePath; /** * Compile the template for efficient rendering * SECURITY FIX #1: Safe template compilation without eval() or Function() * Uses regex-based token replacement instead of dynamic code execution */ /** * Parse section-mode content into named sections. * * Section mode is active when the content contains any <template>, <style>, or * <script> block. In section mode only the <template> section is processed by the * variable substitution engine; <style> and <script> are raw passthrough so that * CSS/JS `}}` characters never trigger unmatched-token errors. * * @see Issue #705 — structured section support for page templates */ static parseSections(content: string): TemplateSections; /** * Return the parsed sections for this template's content. * Result is cached per-instance and cleared whenever content changes. * Used by TemplateRenderer to serve section-specific render results. */ getSections(): TemplateSections; /** * Scan `content` for `{{placeholder}}` patterns and return a merged variable * list. Existing entries are preserved unchanged (user-set descriptions, * types, required flags, etc.); new placeholders are added with defaults: * `type: 'string'`, `required: false`. (#1896) * * Respects section mode — only the `<template>` section is scanned, * matching the substitution engine's scope. * * **Performance:** Single-pass regex scan — O(n) in content length. * Called by `TemplateManager.save()` on every create/edit, so content * is already validated and size-bounded (≤ 100 KB) before reaching here. * * @param content - Raw template content (may include section tags) * @param existingVariables - Already-declared variables; never overwritten * @returns Merged variable list: existing entries first, new entries appended * * @example * // New template — empty schema gets fully populated * deriveVariablesFromContent('Hello {{name}}, score: {{score}}') * // → [{ name: 'name', type: 'string', required: false }, * // { name: 'score', type: 'string', required: false }] * * @example * // Existing entry preserved; only the missing placeholder is added * deriveVariablesFromContent('{{name}} earns {{points}}', [ * { name: 'name', type: 'string', required: true, description: 'Display name' } * ]) * // → [{ name: 'name', type: 'string', required: true, description: 'Display name' }, * // { name: 'points', type: 'string', required: false }] */ static deriveVariablesFromContent(content: string, existingVariables?: TemplateVariable[]): TemplateVariable[]; private compile; /** * Render the template with provided variables * SECURITY FIX #1: Safe rendering without code execution * SECURITY FIX #3: All variables are validated and sanitized * TYPE SAFETY: Strong typing for variables with runtime validation */ render<T extends Record<string, unknown>>(variables?: T, includeDepth?: number): Promise<string>; /** * Validate and sanitize variables according to their definitions * SECURITY FIX #3: Comprehensive validation of all input variables * TYPE SAFETY: Improved type safety for variable validation */ private validateAndSanitizeVariables; /** * Sanitize a single variable value according to its definition * SECURITY FIX #3 & #6: Type-specific validation and Unicode normalization */ private sanitizeVariableValue; /** * Recursively sanitize string values in objects * SECURITY FIX: Truncate deep nesting instead of throwing to prevent DoS */ private sanitizeObject; /** * Resolve nested variable paths (e.g., "user.name") * TYPE SAFETY: Improved type safety for variable resolution */ private resolveVariable; /** * Check if a regex pattern is potentially dangerous (ReDoS) * SECURITY FIX: Detect patterns that could cause exponential backtracking */ private isDangerousRegex; /** * Format a value for template output */ private formatValue; /** * Process template includes * SECURITY FIX #2: Safe include processing with path validation * * TODO: Implement actual include processing functionality * This is currently a placeholder that validates the security model * but does not actually load and render included templates. * * Future implementation should: * 1. Load templates from validated paths * 2. Render them with current variables * 3. Replace include markers in content * 4. Respect includeDepth limit */ private processIncludes; /** * Template-specific validation */ validate(): ElementValidationResult; /** * Serialize to JSON format for internal use and testing */ serializeToJSON(): string; /** * Get content for serialization */ protected getContent(): string; /** * Serialize template to markdown format with YAML frontmatter * FIX: Changed from JSON to markdown for GitHub portfolio compatibility */ serialize(): string; /** * Deserialize template from JSON format */ deserialize(data: string): void; /** * Get a preview of the template with sample data */ preview(): Promise<string>; /** * Template activation lifecycle */ activate(): Promise<void>; /** * Template deactivation lifecycle */ deactivate(): Promise<void>; } //# sourceMappingURL=Template.d.ts.map