Refactor: Implement security restructuring phase
- Implement proxy for external API calls via Edge Functions. - Sanitize logging to remove sensitive data. - Implement input validation.
This commit is contained in:
parent
0ab8fa63d1
commit
8127050bf6
@ -1,80 +1,101 @@
|
||||
|
||||
import { WhatsAppInstance } from '@/types/whatsAppTypes';
|
||||
import { STORAGE_KEY } from './config';
|
||||
/**
|
||||
* Local storage utilities for WhatsApp instances
|
||||
*/
|
||||
|
||||
export const WHATSAPP_STORAGE_KEYS = {
|
||||
INSTANCES: 'whatsappInstances',
|
||||
USER_INSTANCE: 'userWhatsAppInstance',
|
||||
LAST_STATUS_CHECK: 'lastStatusCheck'
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Saves WhatsApp instances to localStorage
|
||||
*/
|
||||
export const saveInstancesToLocalStorage = (
|
||||
instances: WhatsAppInstance[],
|
||||
currentUserId: string
|
||||
): void => {
|
||||
export const saveInstancesToStorage = (instances: any[]): void => {
|
||||
try {
|
||||
console.log(`Saving ${instances.length} instances for user ${currentUserId}`);
|
||||
// Get existing instances from localStorage
|
||||
const savedInstancesStr = localStorage.getItem(STORAGE_KEY);
|
||||
let allInstances: WhatsAppInstance[] = [];
|
||||
|
||||
if (savedInstancesStr) {
|
||||
try {
|
||||
// Parse saved instances
|
||||
const savedInstances = JSON.parse(savedInstancesStr);
|
||||
|
||||
// If it's an array, filter out current user's old instances
|
||||
if (Array.isArray(savedInstances)) {
|
||||
allInstances = savedInstances.filter(
|
||||
(instance: WhatsAppInstance) => instance.userId !== currentUserId
|
||||
);
|
||||
}
|
||||
} catch (parseError) {
|
||||
console.error('Error parsing stored instances, resetting:', parseError);
|
||||
}
|
||||
}
|
||||
|
||||
// Add current user's instances to the array
|
||||
const updatedInstances = [...allInstances, ...instances];
|
||||
|
||||
// Save back to localStorage
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify(updatedInstances));
|
||||
console.log('All WhatsApp instances saved to localStorage:', updatedInstances);
|
||||
localStorage.setItem(WHATSAPP_STORAGE_KEYS.INSTANCES, JSON.stringify(instances));
|
||||
console.log('Instances saved to localStorage:', instances.length);
|
||||
} catch (error) {
|
||||
console.error('Error saving instances to localStorage:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads WhatsApp instances from localStorage for a specific user
|
||||
* Loads WhatsApp instances from localStorage
|
||||
*/
|
||||
export const loadInstancesFromLocalStorage = (
|
||||
userId: string
|
||||
): WhatsAppInstance[] => {
|
||||
export const loadInstancesFromStorage = (): any[] => {
|
||||
try {
|
||||
console.log(`Loading instances for user: ${userId}`);
|
||||
const savedInstancesStr = localStorage.getItem(STORAGE_KEY);
|
||||
console.log('Raw saved instances from localStorage:', savedInstancesStr);
|
||||
|
||||
if (savedInstancesStr && userId) {
|
||||
try {
|
||||
// Parse saved instances
|
||||
const allInstances = JSON.parse(savedInstancesStr);
|
||||
|
||||
// If it's an array, filter by user ID
|
||||
if (Array.isArray(allInstances)) {
|
||||
// Filter instances to only show those belonging to the current user
|
||||
const userInstances = allInstances.filter(
|
||||
(instance: WhatsAppInstance) => instance.userId === userId
|
||||
);
|
||||
console.log(`Found ${userInstances.length} instances for user ${userId}:`, userInstances);
|
||||
return userInstances;
|
||||
}
|
||||
} catch (parseError) {
|
||||
console.error('Error parsing stored instances:', parseError);
|
||||
}
|
||||
const stored = localStorage.getItem(WHATSAPP_STORAGE_KEYS.INSTANCES);
|
||||
if (stored) {
|
||||
const instances = JSON.parse(stored);
|
||||
console.log('Instances loaded from localStorage:', instances.length);
|
||||
return instances;
|
||||
}
|
||||
console.log(`No instances found for user ${userId}`);
|
||||
return [];
|
||||
} catch (error) {
|
||||
console.error("Error loading instances from localStorage:", error);
|
||||
return [];
|
||||
console.error('Error loading instances from localStorage:', error);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves user instance name to localStorage
|
||||
*/
|
||||
export const saveUserInstanceName = (instanceName: string): void => {
|
||||
try {
|
||||
localStorage.setItem(WHATSAPP_STORAGE_KEYS.USER_INSTANCE, instanceName);
|
||||
console.log('User instance name saved:', instanceName);
|
||||
} catch (error) {
|
||||
console.error('Error saving user instance name:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads user instance name from localStorage
|
||||
*/
|
||||
export const loadUserInstanceName = (): string | null => {
|
||||
try {
|
||||
const instanceName = localStorage.getItem(WHATSAPP_STORAGE_KEYS.USER_INSTANCE);
|
||||
console.log('User instance name loaded:', instanceName);
|
||||
return instanceName;
|
||||
} catch (error) {
|
||||
console.error('Error loading user instance name:', error);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears user instance name from localStorage
|
||||
*/
|
||||
export const clearUserInstanceName = (): void => {
|
||||
try {
|
||||
localStorage.removeItem(WHATSAPP_STORAGE_KEYS.USER_INSTANCE);
|
||||
console.log('User instance name cleared from localStorage');
|
||||
} catch (error) {
|
||||
console.error('Error clearing user instance name:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves last status check timestamp
|
||||
*/
|
||||
export const saveLastStatusCheck = (timestamp: number): void => {
|
||||
try {
|
||||
localStorage.setItem(WHATSAPP_STORAGE_KEYS.LAST_STATUS_CHECK, timestamp.toString());
|
||||
} catch (error) {
|
||||
console.error('Error saving last status check:', error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets last status check timestamp
|
||||
*/
|
||||
export const getLastStatusCheck = (): number => {
|
||||
try {
|
||||
const stored = localStorage.getItem(WHATSAPP_STORAGE_KEYS.LAST_STATUS_CHECK);
|
||||
return stored ? parseInt(stored, 10) : 0;
|
||||
} catch (error) {
|
||||
console.error('Error getting last status check:', error);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,192 +1,140 @@
|
||||
|
||||
import { supabase } from "@/integrations/supabase/client";
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
|
||||
/**
|
||||
* Database operations for WhatsApp instances
|
||||
*/
|
||||
|
||||
export interface UserInstanceData {
|
||||
instancia_zap: string | null;
|
||||
status_instancia: string | null;
|
||||
whatsapp: string | null;
|
||||
}
|
||||
|
||||
export interface UserWorkflowData {
|
||||
workflow_id: string | null;
|
||||
/**
|
||||
* Gets user WhatsApp instance information from database
|
||||
*/
|
||||
export async function getUserWhatsAppInstance(userEmail: string): Promise<any> {
|
||||
try {
|
||||
const normalizedEmail = userEmail.toLowerCase().trim();
|
||||
console.log(`Buscando instância para usuário: ${normalizedEmail}`);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('usuarios')
|
||||
.select('instancia_zap, status_instancia, whatsapp, webhook, n8n_workflow_id')
|
||||
.eq('email', normalizedEmail)
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
console.error('Erro ao buscar instância do usuário:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.log('Dados da instância encontrados:', data);
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Erro na operação de busca:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates WhatsApp instance data in the database
|
||||
* Updates user WhatsApp instance information in database
|
||||
*/
|
||||
export async function updateUserWhatsAppInstance(
|
||||
userEmail: string,
|
||||
instanceName: string,
|
||||
status: 'conectado' | 'desconectado'
|
||||
instanceData: {
|
||||
instanceName?: string;
|
||||
status?: string;
|
||||
phoneNumber?: string;
|
||||
webhook?: string;
|
||||
workflowId?: string;
|
||||
}
|
||||
): Promise<void> {
|
||||
try {
|
||||
console.log(`Atualizando instância no banco: ${userEmail} -> ${instanceName} (${status})`);
|
||||
const normalizedEmail = userEmail.toLowerCase().trim();
|
||||
console.log(`Atualizando instância para usuário: ${normalizedEmail}`, instanceData);
|
||||
|
||||
const updateData: any = {};
|
||||
|
||||
if (instanceData.instanceName !== undefined) {
|
||||
updateData.instancia_zap = instanceData.instanceName;
|
||||
}
|
||||
if (instanceData.status !== undefined) {
|
||||
updateData.status_instancia = instanceData.status;
|
||||
}
|
||||
if (instanceData.phoneNumber !== undefined) {
|
||||
updateData.whatsapp = instanceData.phoneNumber;
|
||||
}
|
||||
if (instanceData.webhook !== undefined) {
|
||||
updateData.webhook = instanceData.webhook;
|
||||
}
|
||||
if (instanceData.workflowId !== undefined) {
|
||||
updateData.n8n_workflow_id = instanceData.workflowId;
|
||||
}
|
||||
|
||||
const { error } = await supabase
|
||||
.from('usuarios')
|
||||
.update({
|
||||
instancia_zap: instanceName,
|
||||
status_instancia: status
|
||||
})
|
||||
.eq('email', userEmail.trim().toLowerCase());
|
||||
|
||||
if (error) {
|
||||
console.error('Erro ao atualizar instância WhatsApp:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.log(`Instância WhatsApp atualizada com sucesso: ${instanceName} - ${status}`);
|
||||
} catch (error) {
|
||||
console.error('Erro ao atualizar instância WhatsApp no banco:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets WhatsApp instance data for a user
|
||||
*/
|
||||
export async function getUserWhatsAppInstance(userEmail: string): Promise<UserInstanceData | null> {
|
||||
try {
|
||||
console.log('🔍 getUserWhatsAppInstance - Email recebido:', userEmail);
|
||||
|
||||
const normalizedEmail = userEmail.trim().toLowerCase();
|
||||
console.log('📧 Email normalizado para consulta:', normalizedEmail);
|
||||
|
||||
console.log('🔎 FAZENDO CONSULTA DIRETA NO BANCO...');
|
||||
const { data, error, count } = await supabase
|
||||
.from('usuarios')
|
||||
.select('email, instancia_zap, status_instancia, whatsapp', { count: 'exact' })
|
||||
.update(updateData)
|
||||
.eq('email', normalizedEmail);
|
||||
|
||||
console.log('📊 RESULTADO DA CONSULTA DIRETA:');
|
||||
console.log('- Total de registros encontrados:', count);
|
||||
console.log('- Dados retornados:', JSON.stringify(data, null, 2));
|
||||
console.log('- Erro na consulta:', error);
|
||||
|
||||
if (error) {
|
||||
console.error('❌ Erro na consulta Supabase:', error);
|
||||
console.error('Erro ao atualizar instância:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (!data || data.length === 0) {
|
||||
console.log('⚠️ NENHUM REGISTRO ENCONTRADO para o email:', normalizedEmail);
|
||||
|
||||
// Debug: Show all emails in database
|
||||
const { data: allEmails, error: allError } = await supabase
|
||||
.from('usuarios')
|
||||
.select('email, instancia_zap, status_instancia');
|
||||
|
||||
if (!allError && allEmails) {
|
||||
console.log('📋 TODOS OS EMAILS ENCONTRADOS NO BANCO:');
|
||||
allEmails.forEach((user, index) => {
|
||||
console.log(`${index + 1}. Email no banco: "${user.email}" | Instancia: "${user.instancia_zap}" | Status: "${user.status_instancia}"`);
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const userData = data[0];
|
||||
console.log('✅ USUÁRIO ENCONTRADO! Dados extraídos:');
|
||||
console.log(`- Email do banco: "${userData.email}"`);
|
||||
console.log(`- instancia_zap: "${userData.instancia_zap}" (tipo: ${typeof userData.instancia_zap})`);
|
||||
console.log(`- status_instancia: "${userData.status_instancia}" (tipo: ${typeof userData.status_instancia})`);
|
||||
console.log(`- whatsapp: "${userData.whatsapp}" (tipo: ${typeof userData.whatsapp})`);
|
||||
|
||||
return {
|
||||
instancia_zap: userData.instancia_zap,
|
||||
status_instancia: userData.status_instancia,
|
||||
whatsapp: userData.whatsapp
|
||||
};
|
||||
console.log('✅ Instância atualizada com sucesso');
|
||||
} catch (error) {
|
||||
console.error('💥 Erro crítico ao buscar instância WhatsApp:', error);
|
||||
console.error('❌ Erro ao atualizar instância:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets workflow ID for a user
|
||||
*/
|
||||
export async function getUserWorkflowId(userEmail: string): Promise<string | null> {
|
||||
try {
|
||||
const { data: userData, error: fetchError } = await supabase
|
||||
.from('usuarios')
|
||||
.select('workflow_id')
|
||||
.eq('email', userEmail.trim().toLowerCase())
|
||||
.single();
|
||||
|
||||
if (fetchError) {
|
||||
console.error('❌ Erro ao buscar workflow_id do usuário:', fetchError);
|
||||
throw new Error(`Erro ao buscar workflow_id: ${fetchError.message}`);
|
||||
}
|
||||
|
||||
if (!userData || !userData.workflow_id) {
|
||||
console.error('⚠️ Usuário não possui workflow_id configurado');
|
||||
throw new Error('Usuário não possui workflow configurado');
|
||||
}
|
||||
|
||||
return userData.workflow_id;
|
||||
} catch (error) {
|
||||
console.error('Erro ao buscar workflow_id:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes WhatsApp instance from user
|
||||
* Removes user WhatsApp instance from database
|
||||
*/
|
||||
export async function removeUserWhatsAppInstance(userEmail: string): Promise<void> {
|
||||
try {
|
||||
console.log(`Removendo instância do usuário: ${userEmail}`);
|
||||
const normalizedEmail = userEmail.toLowerCase().trim();
|
||||
console.log(`Removendo instância para usuário: ${normalizedEmail}`);
|
||||
|
||||
const { error } = await supabase
|
||||
.from('usuarios')
|
||||
.update({
|
||||
.update({
|
||||
instancia_zap: null,
|
||||
status_instancia: 'desconectado'
|
||||
status_instancia: 'desconectado',
|
||||
whatsapp: null
|
||||
})
|
||||
.eq('email', userEmail.trim().toLowerCase());
|
||||
.eq('email', normalizedEmail);
|
||||
|
||||
if (error) {
|
||||
console.error('Erro ao remover instância WhatsApp:', error);
|
||||
console.error('Erro ao remover instância:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.log('Instância WhatsApp removida com sucesso');
|
||||
console.log('✅ Instância removida com sucesso');
|
||||
} catch (error) {
|
||||
console.error('Erro ao remover instância WhatsApp do banco:', error);
|
||||
console.error('❌ Erro ao remover instância:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets complete user data for debugging
|
||||
* Gets debug information for a user
|
||||
*/
|
||||
export async function getUserDebugInfo(userEmail: string): Promise<any> {
|
||||
try {
|
||||
console.log('🔍 Buscando informações COMPLETAS do usuário para debug:', userEmail);
|
||||
|
||||
const normalizedEmail = userEmail.trim().toLowerCase();
|
||||
console.log('📧 Email normalizado para debug:', normalizedEmail);
|
||||
const normalizedEmail = userEmail.toLowerCase().trim();
|
||||
console.log(`Buscando informações de debug para: ${normalizedEmail}`);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('usuarios')
|
||||
.select('*')
|
||||
.eq('email', normalizedEmail);
|
||||
.eq('email', normalizedEmail)
|
||||
.single();
|
||||
|
||||
if (error) {
|
||||
console.error('❌ Erro ao buscar informações completas do usuário:', error);
|
||||
console.error('Erro ao buscar debug info:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.log('📊 DADOS COMPLETOS DO USUÁRIO:', JSON.stringify(data, null, 2));
|
||||
return data && data.length > 0 ? data[0] : null;
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('💥 Erro ao buscar informações completas do usuário:', error);
|
||||
console.error('Erro na busca de debug info:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user