feat: add template sanitization to remove API tokens from workflow templates

- Add TemplateSanitizer utility class for detecting and replacing API tokens
- Update template repository to automatically sanitize on save
- Add sanitize:templates command to clean existing templates
- Uses pattern matching to detect various API token formats
- Fixes GitHub push protection blocking database updates

Note: Database will be updated separately after code is deployed

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2025-07-06 13:11:38 +02:00
parent 78b3b99ff7
commit 74f018049d
4 changed files with 248 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
import { DatabaseAdapter } from '../database/database-adapter';
import { TemplateWorkflow, TemplateDetail } from './template-fetcher';
import { logger } from '../utils/logger';
import { TemplateSanitizer } from '../utils/template-sanitizer';
export interface StoredTemplate {
id: number;
@@ -21,7 +22,11 @@ export interface StoredTemplate {
}
export class TemplateRepository {
constructor(private db: DatabaseAdapter) {}
private sanitizer: TemplateSanitizer;
constructor(private db: DatabaseAdapter) {
this.sanitizer = new TemplateSanitizer();
}
/**
* Save a template to the database
@@ -41,6 +46,20 @@ export class TemplateRepository {
// Build URL
const url = `https://n8n.io/workflows/${workflow.id}`;
// Sanitize the workflow to remove API tokens
const { sanitized: sanitizedWorkflow, wasModified } = this.sanitizer.sanitizeWorkflow(detail.workflow);
// Log if we sanitized any tokens
if (wasModified) {
const detectedTokens = this.sanitizer.detectTokens(detail.workflow);
logger.warn(`Sanitized API tokens in template ${workflow.id}: ${workflow.name}`, {
templateId: workflow.id,
templateName: workflow.name,
tokensFound: detectedTokens.length,
tokenPreviews: detectedTokens.map(t => t.substring(0, 20) + '...')
});
}
stmt.run(
workflow.id,
workflow.id,
@@ -50,7 +69,7 @@ export class TemplateRepository {
workflow.user.username,
workflow.user.verified ? 1 : 0,
JSON.stringify(nodeTypes),
JSON.stringify(detail.workflow),
JSON.stringify(sanitizedWorkflow),
JSON.stringify(categories),
workflow.totalViews || 0,
workflow.createdAt,