Files
GPI/src/server/controllers/userController.ts

182 lines
5.5 KiB
TypeScript

import { Request, Response } from 'express';
import { supabase, findOneGpi, queryGpi } from '../config/supabase.js';
import { User } from '../lib/compat.js';
interface AuthRequest extends Request {
appUser?: any;
}
export const syncUser = async (req: AuthRequest, res: Response) => {
try {
// Se já estiver autenticado pelo middleware, usa os dados do appUser
if (req.appUser) {
return res.json(req.appUser);
}
const { email, name, logto_id } = req.body;
if (!email) {
return res.status(400).json({ error: 'Email é obrigatório para sincronização.' });
}
let user = await User.findOne({ email });
if (!user) {
user = await User.create({
email,
name: name || email.split('@')[0],
logto_id,
role: 'guest'
});
} else if (logto_id && !user.logto_id) {
user = await User.findByIdAndUpdate(user.id, { logto_id });
}
res.json(user);
} catch (error: any) {
console.error('Error syncing user:', error);
res.status(500).json({ error: 'Erro ao sincronizar usuário: ' + error.message });
}
};
export const getCurrentUser = async (req: AuthRequest, res: Response) => {
try {
if (!req.appUser) {
// Se o middleware não encontrou, tenta autenticar novamente aqui para garantir
const user = await User.findOne({ id: (req as any).headers['x-user-id'] }); // Fallback opcional
if (!user) {
return res.status(404).json({ error: 'Usuário não autenticado ou não encontrado no banco.' });
}
return res.json(user);
}
res.json(req.appUser);
} catch (error: any) {
console.error('Error getting current user:', error);
res.status(500).json({ error: 'Erro ao buscar perfil do usuário.' });
}
};
export const getAllUsers = async (req: Request, res: Response) => {
try {
const organizationId = req.headers['x-organization-id'] as string;
if (!organizationId) {
return res.status(400).json({ error: 'Organização não selecionada.' });
}
const { data, error } = await supabase
.from('user_organizations')
.select('*, users(*)')
.eq('organization_id', organizationId);
if (error) throw error;
res.json(data || []);
} catch (error: any) {
console.error('Error getting users:', error);
res.status(500).json({ error: 'Erro ao buscar usuários.' });
}
};
export const updateUserRole = async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const { role } = req.body;
if (!['guest', 'user', 'admin'].includes(role)) {
return res.status(400).json({ error: 'Role inválido.' });
}
const { data, error } = await supabase
.from('user_organizations')
.update({ role })
.eq('id', id)
.select()
.single();
if (error) throw error;
res.json(data);
} catch (error: any) {
console.error('Error updating role:', error);
res.status(500).json({ error: 'Erro ao alterar role.' });
}
};
export const toggleBanUser = async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const { isBanned } = req.body;
const { data, error } = await supabase
.from('user_organizations')
.update({ is_banned: isBanned })
.eq('id', id)
.select()
.single();
if (error) throw error;
res.json(data);
} catch (error: any) {
console.error('Error toggling ban:', error);
res.status(500).json({ error: 'Erro ao alterar banimento.' });
}
};
export const heartbeat = async (req: AuthRequest, res: Response) => {
try {
if (!req.appUser) {
return res.status(401).json({ error: 'Não autenticado.' });
}
await supabase
.from('users')
.update({ last_seen_at: new Date().toISOString() })
.eq('id', req.appUser.id);
res.status(200).send();
} catch (error) {
console.error('Heartbeat error:', error);
res.status(500).send();
}
};
export const getActiveUsers = async (req: AuthRequest, res: Response) => {
try {
const organizationId = req.headers['x-organization-id'] as string;
if (!organizationId) {
return res.status(400).json([]);
}
const twoMinutesAgo = new Date(Date.now() - 2 * 60 * 1000).toISOString();
const { data, error } = await supabase
.from('users')
.select('id, email, name, last_seen_at')
.gte('last_seen_at', twoMinutesAgo);
if (error) throw error;
res.json(data || []);
} catch (error: any) {
console.error('Error getting active users:', error);
res.status(500).json([]);
}
};
export const deleteUser = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const { error } = await supabase
.from('user_organizations')
.delete()
.eq('id', id);
if (error) throw error;
res.json({ message: 'Membro removido com sucesso.' });
} catch (error: any) {
console.error('Error deleting user:', error);
res.status(500).json({ error: 'Erro ao remover membro.' });
}
};