194 lines
5.6 KiB
TypeScript
194 lines
5.6 KiB
TypeScript
import { Request, Response } from 'express';
|
|
import { supabase } from '../config/supabase.js';
|
|
|
|
interface AuthRequest extends Request {
|
|
appUser?: any;
|
|
}
|
|
|
|
export const syncUser = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
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.' });
|
|
}
|
|
|
|
const { data: existingUser } = await supabase
|
|
.from('users')
|
|
.select('*')
|
|
.eq('email', email)
|
|
.single();
|
|
|
|
let user;
|
|
if (!existingUser) {
|
|
const { data, error } = await supabase
|
|
.from('users')
|
|
.insert({
|
|
email,
|
|
name: name || email.split('@')[0],
|
|
logto_id,
|
|
role: 'guest'
|
|
})
|
|
.select()
|
|
.single();
|
|
|
|
if (error) throw error;
|
|
user = data;
|
|
} else {
|
|
if (logto_id && !existingUser.logto_id) {
|
|
const { data } = await supabase
|
|
.from('users')
|
|
.update({ logto_id })
|
|
.eq('id', existingUser.id)
|
|
.select()
|
|
.single();
|
|
user = data;
|
|
} else {
|
|
user = existingUser;
|
|
}
|
|
}
|
|
|
|
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) {
|
|
return res.json({
|
|
id: 'guest-user',
|
|
email: 'guest@gpi.app',
|
|
name: 'Guest User',
|
|
role: 'user'
|
|
});
|
|
}
|
|
res.json(req.appUser);
|
|
} catch (error: any) {
|
|
console.error('Error getting current user:', error);
|
|
res.json(req.appUser || { id: 'guest-user', email: 'guest@gpi.app', role: 'user' });
|
|
}
|
|
};
|
|
|
|
export const getAllUsers = async (req: Request, res: Response) => {
|
|
try {
|
|
// Always return all users from users table for now
|
|
const { data, error } = await supabase
|
|
.from('users')
|
|
.select('*');
|
|
|
|
if (error) {
|
|
console.log('Error fetching users:', error.message);
|
|
return res.json([]);
|
|
}
|
|
|
|
return res.json(data || []);
|
|
} catch (error: any) {
|
|
console.error('Error getting users:', error);
|
|
res.json([]);
|
|
}
|
|
};
|
|
|
|
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 && error.code !== '42P01') throw error;
|
|
res.json(data || { message: 'Role atualizado' });
|
|
} catch (error: any) {
|
|
console.error('Error updating role:', error);
|
|
res.json({ message: 'Role atualizado' });
|
|
}
|
|
};
|
|
|
|
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 && error.code !== '42P01') throw error;
|
|
res.json(data || { message: 'Ban atualizado' });
|
|
} catch (error: any) {
|
|
console.error('Error toggling ban:', error);
|
|
res.json({ message: 'Ban atualizado' });
|
|
}
|
|
};
|
|
|
|
export const heartbeat = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
if (!req.appUser) {
|
|
return res.status(200).send();
|
|
}
|
|
|
|
try {
|
|
await supabase
|
|
.from('users')
|
|
.update({ last_seen_at: new Date().toISOString() })
|
|
.eq('id', req.appUser.id);
|
|
} catch (e) { /* ignore */ }
|
|
|
|
res.status(200).send();
|
|
} catch (error) {
|
|
console.error('Heartbeat error:', error);
|
|
res.status(200).send();
|
|
}
|
|
};
|
|
|
|
export const getActiveUsers = async (req: AuthRequest, res: Response) => {
|
|
try {
|
|
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 && error.code !== '42P01') throw error;
|
|
res.json(data || []);
|
|
} catch (error: any) {
|
|
console.error('Error getting active users:', error);
|
|
res.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 && error.code !== '42P01') throw error;
|
|
res.json({ message: 'Membro removido com sucesso.' });
|
|
} catch (error: any) {
|
|
console.error('Error deleting user:', error);
|
|
res.json({ message: 'Membro removido com sucesso.' });
|
|
}
|
|
}; |