/* SoftSins Audio Generation System - SECURE VERSION */ console.log('🎵 Loading audio-generator-secure.js...'); class AudioGeneratorSecure { constructor() { this.supabase = window.supabase; // 🔒 SECURE: Use Supabase Edge Function instead of direct Lambda this.previewEndpoint = `${this.supabase.supabaseUrl}/functions/v1/generate-preview-audio`; console.log('🔒 AudioGeneratorSecure using Edge Function:', this.previewEndpoint); this.init(); } async init() { console.log('🔒 AudioGeneratorSecure initialized'); } async generatePreview(selections, audioFileId) { console.log('🎬 Starting SECURE preview generation for:', audioFileId); try { // 🔒 Get current user authentication const { data: { user }, error: authError } = await this.supabase.auth.getUser(); if (authError || !user) { throw new Error('Authentication required for preview generation'); } // 🔒 Get auth token for Edge Function const { data: { session }, error: sessionError } = await this.supabase.auth.getSession(); if (sessionError || !session) { throw new Error('Valid session required for preview generation'); } console.log('🔒 User authenticated, calling secure Edge Function...'); // 🔒 SECURE: Call Supabase Edge Function instead of Lambda directly const response = await fetch(this.previewEndpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${session.access_token}`, 'apikey': this.supabase.supabaseKey }, body: JSON.stringify({ selections: selections, audioFileId: audioFileId, userId: user.id }) }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || `Request failed: ${response.status}`); } const result = await response.json(); console.log('✅ SECURE preview generation completed:', result); // 🔒 Save story data securely via Supabase (bereits in Edge Function gemacht) return { ...result, audioUrl: result.audio_url, success: true }; } catch (error) { console.error('❌ SECURE preview generation failed:', error); // User-friendly error handling if (error.message.includes('Authentication required')) { // Redirect to login or show auth modal if (window.openLoginModal) { window.openLoginModal(); } throw new Error('Bitte melden Sie sich an, um eine Vorschau zu generieren.'); } if (error.message.includes('Rate limit')) { throw new Error('Sie haben zu viele Vorschauen generiert. Bitte warten Sie eine Stunde.'); } throw error; } } async generateFull(selections, audioFileId) { // Full generation bleibt über Stripe Webhook - ist bereits sicher console.log('🎭 Full generation handled via Stripe webhook - already secure'); throw new Error('Full generation is handled via purchase flow'); } // Utility method für Testing der sicheren Verbindung async testSecureConnection() { try { const { data: { user } } = await this.supabase.auth.getUser(); if (!user) { console.log('❌ No authenticated user for connection test'); return false; } const testSelections = { firstName: 'Test', eyeColor: 'braun', hairColor: 'blond' }; const testResult = await this.generatePreview(testSelections, 'test-' + Date.now()); console.log('✅ Secure connection test successful:', testResult); return true; } catch (error) { console.error('❌ Secure connection test failed:', error); return false; } } // Backwards compatibility method personalizeTemplate(templateType, selections, audioFileId) { console.warn('⚠️ personalizeTemplate is now handled securely on the server side'); return null; } createReplacementMap(selections, filename) { console.warn('⚠️ createReplacementMap is now handled securely on the server side'); return {}; } sendToAWS(templateData) { console.warn('⚠️ sendToAWS is now handled securely via Edge Functions'); throw new Error('Direct AWS access is disabled for security. Use generatePreview() instead.'); } // Legacy methods für Kompatibilität mit bestehendem Code async updateSupabaseStatus(audioFileId, field, value) { console.log(`🔒 updateSupabaseStatus handled securely in Edge Function`); return true; } getPreviewFilename(selections, audioFileId) { return `${audioFileId}_WEIHNACHTEN_preview.mp3`; } getFullFilename(selections, audioFileId) { return `${audioFileId}_WEIHNACHTEN_full.mp3`; } getEyeColorText(eyeColor) { const eyeColorMap = { 'braun': 'braunen', 'blau': 'blauen', 'gruen': 'grünen', 'grau': 'grauen', 'bunt': 'bunten', 'andere': 'schönen' }; return eyeColorMap[eyeColor] || 'braunen'; } getHairColorText(hairColor) { const hairColorMap = { 'blond': 'blonden', 'braun': 'braunen', 'schwarz': 'schwarzen', 'rot': 'roten', 'grau': 'grauen', 'bunt': 'bunten', 'andere': 'schönen' }; return hairColorMap[hairColor] || 'braunen'; } applyReplacements(template, replacements) { console.warn('⚠️ applyReplacements is now handled securely on the server side'); return template; } async loadTemplates() { console.log('🔒 Templates now loaded from secure Supabase database'); return true; } } // Make AudioGeneratorSecure available globally window.AudioGeneratorSecure = AudioGeneratorSecure; // Initialize secure version when ready function initializeSecureAudioGenerator() { console.log('🔄 Attempting SECURE AudioGenerator initialization...', { supabase: !!window.supabase, audioGeneratorSecure: !!window.audioGeneratorSecure }); if (window.supabase && !window.audioGeneratorSecure) { window.audioGeneratorSecure = new AudioGeneratorSecure(); // Replace old audio generator with secure version window.audioGenerator = window.audioGeneratorSecure; console.log('🔒 SECURE AudioGenerator available globally'); return true; } else if (!window.supabase) { console.warn('⚠️ Supabase not available yet for secure audio generator'); } else if (window.audioGeneratorSecure) { console.log('✅ SECURE AudioGenerator already initialized'); return true; } return false; } // Auto-initialize if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { setTimeout(initializeSecureAudioGenerator, 100); }); } else { setTimeout(initializeSecureAudioGenerator, 100); } window.initializeSecureAudioGenerator = initializeSecureAudioGenerator; console.log('🔒 audio-generator-secure.js loaded');