import { sql } from '../../../../lib/sql.js'; import { getUserFromRequest } from '../../../../lib/permission-middleware'; import { isValidSlug } from '../../../../lib/slug-utils'; export default async function handler(req, res) { try { // Get authenticated user const user = await getUserFromRequest(req); if (!user) { return res.status(401).json({ error: 'Authentication required' }); } const { identifier } = req.query; if (!identifier) { return res.status(400).json({ error: 'Collection identifier is required' }); } // Determine if identifier is a slug or numeric ID const isSlug = isValidSlug(identifier) || isNaN(parseInt(identifier)); // Get collection and verify ownership let collectionResult; if (isSlug) { collectionResult = await sql` SELECT * FROM collections WHERE slug = ${identifier} AND user_id = ${user.userId} `; } else { const numericId = parseInt(identifier); collectionResult = await sql` SELECT * FROM collections WHERE id = ${numericId} AND user_id = ${user.userId} `; } if (collectionResult.rows.length === 0) { return res.status(404).json({ error: 'Collection not found or you do not have permission to manage permissions' }); } const collection = collectionResult.rows[0]; if (req.method === 'GET') { // Get all permissions for this collection const permissionsResult = await sql` SELECT cp.*, u.email, u.first_name, u.last_name FROM collection_permissions cp JOIN users u ON cp.user_id = u.id WHERE cp.collection_id = ${collection.id} ORDER BY cp.created_at DESC `; const permissions = permissionsResult.rows.map(perm => ({ id: perm.id, userId: perm.user_id, email: perm.email, firstName: perm.first_name, lastName: perm.last_name, role: perm.role, status: perm.status, createdAt: perm.created_at, updatedAt: perm.updated_at })); res.status(200).json({ permissions }); } else if (req.method === 'POST') { // Add new permission const { email, role = 'viewer' } = req.body; if (!email) { return res.status(400).json({ error: 'Email is required' }); } if (!['viewer', 'editor', 'owner'].includes(role)) { return res.status(400).json({ error: 'Invalid role. Must be viewer, editor, or owner' }); } // Find user by email const userResult = await sql` SELECT id FROM users WHERE email = ${email} `; if (userResult.length === 0) { return res.status(404).json({ error: 'User not found' }); } const targetUserId = userResult[0].id; // Check if permission already exists const existingResult = await sql` SELECT id FROM collection_permissions WHERE collection_id = ${collection.id} AND user_id = ${targetUserId} `; if (existingResult.length > 0) { return res.status(400).json({ error: 'User already has permissions for this collection' }); } // Create new permission const result = await sql` INSERT INTO collection_permissions (collection_id, user_id, role, status) VALUES (${collection.id}, ${targetUserId}, ${role}, 'active') RETURNING * `; res.status(201).json({ message: 'Permission added successfully', permission: result[0] }); } else if (req.method === 'PUT') { // Update existing permission const { permissionId, role, status } = req.body; if (!permissionId) { return res.status(400).json({ error: 'Permission ID is required' }); } const updateFields = []; const updateValues = []; let paramIndex = 1; if (role !== undefined) { if (!['viewer', 'editor', 'owner'].includes(role)) { return res.status(400).json({ error: 'Invalid role' }); } updateFields.push(`role = $${paramIndex}`); updateValues.push(role); paramIndex++; } if (status !== undefined) { if (!['active', 'pending', 'revoked'].includes(status)) { return res.status(400).json({ error: 'Invalid status' }); } updateFields.push(`status = $${paramIndex}`); updateValues.push(status); paramIndex++; } if (updateFields.length === 0) { return res.status(400).json({ error: 'No fields to update' }); } updateFields.push('updated_at = CURRENT_TIMESTAMP'); updateValues.push(permissionId, collection.id); const updateQuery = ` UPDATE collection_permissions SET ${updateFields.join(', ')} WHERE id = $${paramIndex} AND collection_id = $${paramIndex + 1} RETURNING * `; const result = await sql.query(updateQuery, updateValues); if (result.length === 0) { return res.status(404).json({ error: 'Permission not found' }); } res.status(200).json({ message: 'Permission updated successfully', permission: result[0] }); } else if (req.method === 'DELETE') { // Remove permission const { permissionId } = req.body; if (!permissionId) { return res.status(400).json({ error: 'Permission ID is required' }); } const result = await sql` DELETE FROM collection_permissions WHERE id = ${permissionId} AND collection_id = ${collection.id} RETURNING * `; if (result.length === 0) { return res.status(404).json({ error: 'Permission not found' }); } res.status(200).json({ message: 'Permission removed successfully' }); } else { res.status(405).json({ error: 'Method not allowed' }); } } catch (error) { console.error('Collection permissions API error:', error); res.status(500).json({ error: 'Internal server error' }); } }