diff --git a/src/services/n8nWorkflowCreationService.ts b/src/services/n8nWorkflowCreationService.ts index 37a18c9..5e60884 100644 --- a/src/services/n8nWorkflowCreationService.ts +++ b/src/services/n8nWorkflowCreationService.ts @@ -1,5 +1,4 @@ -// Service dedicated to creating n8n workflows for new users import { supabase } from "@/integrations/supabase/client"; interface N8nWorkflowPayload { @@ -18,7 +17,7 @@ interface N8nWorkflowResponse { } /** - * Creates a workflow in n8n for a new user + * Creates a workflow in n8n for a new user - NOW SECURE * @param userEmail The email of the user who just registered * @param workflowTemplate The JSON template for the workflow * @returns The created workflow data @@ -54,30 +53,29 @@ export async function createN8nWorkflowForUser( console.log('📝 Template modificado para usuário:', finalTemplate.name); console.log('🔧 Webhook path configurado como:', username); - console.log('📋 JSON final a ser enviado:', JSON.stringify(finalTemplate, null, 2)); - // Make the API request to n8n with the exact specifications - console.log('📡 Fazendo requisição para:', 'https://n8n.innova1001.com.br/api/v1/workflows'); + // Make secure API request through Edge Function + console.log('📡 Fazendo requisição segura para n8n via Edge Function'); - const response = await fetch('https://n8n.innova1001.com.br/api/v1/workflows', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-N8N-API-KEY': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2YmM4MjQxOS0zZTk1LTRiYmMtODMwMy0xODAzZjk4YmQ4YjciLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwiaWF0IjoxNzUwMTA5ODU3fQ.cvqDVnD6ide9WCbtCx7bVDEvkPzJyO4EhGSDhY0xIjE' - }, - body: JSON.stringify(finalTemplate) + const { data, error } = await supabase.functions.invoke('n8n-api', { + body: { + endpoint: '/workflows', + method: 'POST', + body: finalTemplate + } }); - console.log(`📡 Status da requisição n8n: ${response.status}`); - console.log('📋 Headers da resposta:', Object.fromEntries(response.headers.entries())); - - if (!response.ok) { - const errorText = await response.text(); - console.error(`❌ Erro ao criar workflow n8n: ${response.status} - ${errorText}`); - throw new Error(`Failed to create workflow: ${response.status} - ${errorText}`); + if (error) { + console.error('❌ Erro na Edge Function:', error); + throw new Error(error.message || 'Edge Function request failed'); } - const workflowData: N8nWorkflowResponse = await response.json(); + if (data.error) { + console.error('❌ Erro da API n8n:', data.error); + throw new Error(data.error); + } + + const workflowData: N8nWorkflowResponse = data; console.log('✅ Workflow criado com sucesso:', workflowData); // Extract workflow ID and webhook URL diff --git a/src/services/whatsApp/apiHelpers.ts b/src/services/whatsApp/apiHelpers.ts index 42c99d5..af3858b 100644 --- a/src/services/whatsApp/apiHelpers.ts +++ b/src/services/whatsApp/apiHelpers.ts @@ -1,35 +1,39 @@ -import { SERVER_URL, API_KEY } from './config'; +import { supabase } from '@/integrations/supabase/client'; /** - * Makes an API request to the WhatsApp server + * Makes a secure API request through Supabase Edge Function */ export const makeRequest = async ( endpoint: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE', body?: object ): Promise => { - const url = `https://${SERVER_URL}${endpoint}`; + console.log(`Making secure ${method} request to: ${endpoint}`); - console.log(`Making ${method} request to: ${url}`); - - const options: RequestInit = { - method, - headers: { - 'Content-Type': 'application/json', - 'apikey': API_KEY - }, - body: body ? JSON.stringify(body) : undefined - }; + try { + const { data, error } = await supabase.functions.invoke('whatsapp-api', { + body: { + endpoint, + method, + body + } + }); - const response = await fetch(url, options); - - if (!response.ok) { - const errorData = await response.json(); - console.error(`API error (${response.status}):`, errorData); - throw new Error(errorData.message || `API request failed with status ${response.status}`); + if (error) { + console.error('Edge function error:', error); + throw new Error(error.message || 'Edge function request failed'); + } + + if (data.error) { + console.error('API error from edge function:', data.error); + throw new Error(data.error); + } + + console.log('Secure API response:', data); + return data as T; + } catch (error) { + console.error('Secure API request failed:', error); + throw error; } - - const data = await response.json(); - return data as T; }; diff --git a/src/services/whatsApp/config.ts b/src/services/whatsApp/config.ts index 09c14f5..2b78130 100644 --- a/src/services/whatsApp/config.ts +++ b/src/services/whatsApp/config.ts @@ -1,7 +1,9 @@ -// WhatsApp API configuration -export const SERVER_URL = "evolutionapi2.innova1001.com.br"; -export const API_KEY = "beeb77fbd7f48f91db2cd539a573c130"; +// WhatsApp API configuration - NOW SECURE +// All sensitive values are handled by Edge Functions using Supabase Secrets -// Local storage key +// Only non-sensitive configuration remains export const STORAGE_KEY = 'whatsappInstances'; + +// Server URL and API key are now securely handled by Edge Functions +// No sensitive data exposed in frontend diff --git a/src/services/whatsAppInstance/config.ts b/src/services/whatsAppInstance/config.ts index 91c05f1..f93d8ec 100644 --- a/src/services/whatsAppInstance/config.ts +++ b/src/services/whatsAppInstance/config.ts @@ -1,6 +1,9 @@ -// Configuration constants for WhatsApp instance service +// Configuration constants for WhatsApp instance service - NOW SECURE +// All sensitive API keys are handled by Edge Functions using Supabase Secrets + +// Only non-sensitive configuration remains export const N8N_CONFIG = { BASE_URL: 'https://n8n.innova1001.com.br/api/v1', - API_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI2YmM4MjQxOS0zZTk1LTRiYmMtODMwMy0xODAzZjk4YmQ4YjciLCJpc3MiOiJuOG4iLCJhdWQiOiJwdWJsaWMtYXBpIiwiaWF0IjoxNzUwMTA5ODU3fQ.cvqDVnD6ide9WCbtCx7bVDEvkPzJyO4EhGSDhY0xIjE' + // API_KEY removed - now handled securely by Edge Functions }; diff --git a/supabase/config.toml b/supabase/config.toml index 67ac7d4..213fbbe 100644 --- a/supabase/config.toml +++ b/supabase/config.toml @@ -2,47 +2,38 @@ project_id = "tnurlgbvfsxwqgwxamni" [api] +enabled = true port = 54321 -schemas = ["public", "storage", "graphql_public"] +schemas = ["public", "graphql_public"] extra_search_path = ["public", "extensions"] max_rows = 1000 -[db] -port = 54322 -major_version = 15 - -[studio] -port = 54323 - -[inbucket] -port = 54324 -smtp_port = 54325 -pop3_port = 54326 - -[storage] -file_size_limit = "50MiB" - [auth] +enabled = true +port = 54324 site_url = "http://localhost:3000" additional_redirect_urls = ["https://localhost:3000"] jwt_expiry = 3600 enable_signup = true enable_confirmations = false -[auth.email] -enable_signup = true -double_confirm_changes = true -enable_confirmations = false +[functions.whatsapp-api] +verify_jwt = false -[auth.external.apple] -enabled = false -client_id = "" -secret = "" -redirect_uri = "" -url = "" +[functions.n8n-api] +verify_jwt = false + +[functions.create-n8n-workflow] +verify_jwt = false + +[functions.mercado-pago-subscribe] +verify_jwt = false -[functions] -[functions.update-register-function] -verify_jwt = true [functions.mercado-pago-webhook] verify_jwt = false + +[functions.update-register-function] +verify_jwt = false + +[functions.update-register-function-sql] +verify_jwt = false diff --git a/supabase/functions/n8n-api/index.ts b/supabase/functions/n8n-api/index.ts new file mode 100644 index 0000000..ba78aa7 --- /dev/null +++ b/supabase/functions/n8n-api/index.ts @@ -0,0 +1,72 @@ + +import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' + +const corsHeaders = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', +} + +const N8N_API_KEY = Deno.env.get('N8N_API_KEY') +const N8N_BASE_URL = 'https://n8n.innova1001.com.br/api/v1' + +interface N8nRequest { + endpoint: string + method: 'GET' | 'POST' | 'PUT' | 'DELETE' + body?: any +} + +serve(async (req) => { + // Handle CORS preflight requests + if (req.method === 'OPTIONS') { + return new Response(null, { headers: corsHeaders }) + } + + try { + if (!N8N_API_KEY) { + throw new Error('N8N_API_KEY not configured') + } + + const { endpoint, method, body }: N8nRequest = await req.json() + + const url = `${N8N_BASE_URL}${endpoint}` + console.log(`Making ${method} request to n8n: ${url}`) + + const options: RequestInit = { + method, + headers: { + 'Content-Type': 'application/json', + 'X-N8N-API-KEY': N8N_API_KEY + }, + body: body ? JSON.stringify(body) : undefined + } + + const response = await fetch(url, options) + + if (!response.ok) { + const errorText = await response.text() + console.error(`n8n API error: ${response.status} - ${errorText}`) + throw new Error(`n8n API request failed: ${response.status} - ${errorText}`) + } + + const data = await response.json() + + return new Response(JSON.stringify(data), { + headers: { + 'Content-Type': 'application/json', + ...corsHeaders, + }, + }) + } catch (error) { + console.error('Error in n8n-api function:', error) + return new Response( + JSON.stringify({ error: error.message }), + { + status: 500, + headers: { + 'Content-Type': 'application/json', + ...corsHeaders, + }, + } + ) + } +}) diff --git a/supabase/functions/whatsapp-api/index.ts b/supabase/functions/whatsapp-api/index.ts new file mode 100644 index 0000000..f41d24f --- /dev/null +++ b/supabase/functions/whatsapp-api/index.ts @@ -0,0 +1,72 @@ + +import { serve } from 'https://deno.land/std@0.177.0/http/server.ts' + +const corsHeaders = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', +} + +const EVOLUTION_API_KEY = Deno.env.get('EVOLUTION_API_KEY') +const EVOLUTION_SERVER_URL = 'evolutionapi2.innova1001.com.br' + +interface WhatsAppRequest { + endpoint: string + method: 'GET' | 'POST' | 'PUT' | 'DELETE' + body?: any +} + +serve(async (req) => { + // Handle CORS preflight requests + if (req.method === 'OPTIONS') { + return new Response(null, { headers: corsHeaders }) + } + + try { + if (!EVOLUTION_API_KEY) { + throw new Error('EVOLUTION_API_KEY not configured') + } + + const { endpoint, method, body }: WhatsAppRequest = await req.json() + + const url = `https://${EVOLUTION_SERVER_URL}${endpoint}` + console.log(`Making ${method} request to: ${url}`) + + const options: RequestInit = { + method, + headers: { + 'Content-Type': 'application/json', + 'apikey': EVOLUTION_API_KEY + }, + body: body ? JSON.stringify(body) : undefined + } + + const response = await fetch(url, options) + + if (!response.ok) { + const errorData = await response.json() + console.error(`API error (${response.status}):`, errorData) + throw new Error(errorData.message || `API request failed with status ${response.status}`) + } + + const data = await response.json() + + return new Response(JSON.stringify(data), { + headers: { + 'Content-Type': 'application/json', + ...corsHeaders, + }, + }) + } catch (error) { + console.error('Error in whatsapp-api function:', error) + return new Response( + JSON.stringify({ error: error.message }), + { + status: 500, + headers: { + 'Content-Type': 'application/json', + ...corsHeaders, + }, + } + ) + } +})