const nocodbService = require('../services/nocodb'); const logger = require('../utils/logger'); const config = require('../config'); const { sanitizeUser, extractId } = require('../utils/helpers'); const { sendLoginDetails } = require('../services/email'); class UsersController { async getAll(req, res) { try { // Debug logging logger.info('UsersController.getAll called'); logger.info('loginSheetId from config:', config.nocodb.loginSheetId); logger.info('NocoDB config:', { apiUrl: config.nocodb.apiUrl, hasToken: !!config.nocodb.apiToken, projectId: config.nocodb.projectId, tableId: config.nocodb.tableId, loginSheetId: config.nocodb.loginSheetId }); if (!config.nocodb.loginSheetId) { logger.error('Login sheet not configured in environment'); return res.status(500).json({ success: false, error: 'Login sheet not configured. Please set NOCODB_LOGIN_SHEET in your environment variables.' }); } logger.info('Fetching users from NocoDB...'); // Remove the sort parameter that's causing the error const response = await nocodbService.getAll(config.nocodb.loginSheetId, { limit: 100 // Removed: sort: '-created_at' }); const users = response.list || []; logger.info(`Retrieved ${users.length} users from database`); // Remove password field from response for security const safeUsers = users.map(sanitizeUser); res.json({ success: true, users: safeUsers }); } catch (error) { logger.error('Error fetching users:', error); res.status(500).json({ success: false, error: 'Failed to fetch users: ' + error.message }); } } async create(req, res) { try { const { email, password, name, isAdmin, userType, expireDays } = req.body; if (!email || !password) { return res.status(400).json({ success: false, error: 'Email and password are required' }); } if (!config.nocodb.loginSheetId) { return res.status(500).json({ success: false, error: 'Login sheet not configured' }); } // Check if user already exists const existingUser = await nocodbService.getUserByEmail(email); if (existingUser) { return res.status(400).json({ success: false, error: 'User with this email already exists' }); } // Calculate expiration date for temp users let expiresAt = null; if (userType === 'temp' && expireDays) { const expirationDate = new Date(); expirationDate.setDate(expirationDate.getDate() + expireDays); expiresAt = expirationDate.toISOString(); } // Create new user - use the actual column names from your table const userData = { Email: email, email: email, Password: password, password: password, Name: name || '', name: name || '', Admin: isAdmin === true, admin: isAdmin === true, UserType: userType || 'user', userType: userType || 'user', CreatedAt: new Date().toISOString(), ExpiresAt: expiresAt, ExpireDays: userType === 'temp' ? expireDays : null }; const response = await nocodbService.create( config.nocodb.loginSheetId, userData ); res.status(201).json({ success: true, message: 'User created successfully', user: { id: extractId(response), email: email, name: name, admin: isAdmin, userType: userType, expiresAt: expiresAt } }); } catch (error) { logger.error('Error creating user:', error); res.status(500).json({ success: false, error: 'Failed to create user' }); } } async delete(req, res) { try { const userId = req.params.id; if (!config.nocodb.loginSheetId) { return res.status(500).json({ success: false, error: 'Login sheet not configured' }); } // Don't allow admins to delete themselves if (userId === req.session.userId) { return res.status(400).json({ success: false, error: 'Cannot delete your own account' }); } await nocodbService.delete( config.nocodb.loginSheetId, userId ); res.json({ success: true, message: 'User deleted successfully' }); } catch (error) { logger.error('Error deleting user:', error); res.status(500).json({ success: false, error: 'Failed to delete user' }); } } async sendLoginDetails(req, res) { try { const userId = req.params.id; if (!config.nocodb.loginSheetId) { return res.status(500).json({ success: false, error: 'Login sheet not configured' }); } // Get user data from database const user = await nocodbService.getById( config.nocodb.loginSheetId, userId ); if (!user) { return res.status(404).json({ success: false, error: 'User not found' }); } // Send login details email await sendLoginDetails(user); res.json({ success: true, message: 'Login details sent successfully' }); } catch (error) { logger.error('Error sending login details:', error); res.status(500).json({ success: false, error: 'Failed to send login details' }); } } } module.exports = new UsersController();