UNPKG

streamby-core

Version:

StreamBy middleware framework for media storage management

324 lines (323 loc) 16.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.projectRouter = projectRouter; const express_1 = require("express"); const manager_1 = require("../../models/manager"); const auth_1 = require("../../utils/auth"); const connectionManager_1 = require("../../adapters/database/connectionManager"); const sql_1 = require("../../adapters/database/sql"); const auth_2 = require("../../services/auth"); function projectRouter(config) { const router = (0, express_1.Router)(); router.use((0, auth_2.authenticate)(config)); const Project = (0, manager_1.getModel)('projects'); const mapProjectToResponseFormat = (project, userId) => { const currentUserMember = project.members?.find((member) => member.userId === userId); return { id: project._id || project.id, dbType: project.dbType, name: project.name, image: project.image || '', archived: currentUserMember ? currentUserMember.archived || false : false, }; }; router.get('/projects', async (req, res) => { try { const auth = req.auth; const archivedQuery = req.query.archived; const filterArchived = archivedQuery !== undefined ? String(archivedQuery).toLowerCase() === 'true' : undefined; const allProjects = await Project.find({}); // Fetch all projects const projects = allProjects .filter(project => { const isMember = project.members?.some((m) => m.userId?.toString() === auth.userId?.toString()); if (!isMember) return false; if (filterArchived !== undefined) { const currentUserMember = project.members?.find((member) => member.userId === auth.userId); return currentUserMember ? (currentUserMember.archived || false) === filterArchived : false; } return true; }) .map(project => mapProjectToResponseFormat(project, auth.userId)); res.json({ projects, message: 'Projects listed successfully' }); } catch (err) { console.error('Error in /projects endpoint:', err); res.status(500).json({ message: 'Failed to list projects', details: err }); } }); router.post('/projects/create', async (req, res) => { try { const auth = req.auth; if (auth.role !== 'admin' && auth.role !== 'editor') { return res.status(403).json({ message: 'Permission denied' }); } const { name, description, dbType, image, allowedOrigin } = req.body; const mainDb = config.databases?.find(db => db.main); if (!mainDb) { return res.status(500).json({ message: 'Main database not configured' }); } const userDbType = mainDb.type; const User = (0, manager_1.getModel)('users', userDbType); const user = await User.findOne({ _id: auth.userId }); if (!user) { return res.status(404).json({ message: 'User not found' }); } const newProject = await Project.create({ dbType: dbType || 'nosql', name, description: description || '', image: image || '', allowedOrigin: allowedOrigin || [], members: [{ userId: auth.userId, username: user.username, role: "admin", archived: false }], }); const allProjects = await Project.find({}); const projects = allProjects .filter(project => { const isMember = project.members?.some((m) => m.userId?.toString() === auth.userId?.toString()); return isMember; // Only include projects where the user is a member }) .map(project => mapProjectToResponseFormat(project, auth.userId)); res.status(200).json({ success: true, projects: projects, projectId: newProject._id || newProject.id, message: 'Project created successfully' }); } catch (err) { console.error('Error creating project:', err); res.status(500).json({ message: 'Failed to create project', details: err.message }); } }); router.get('/projects/:id', async (req, res) => { try { const auth = req.auth; const projectId = req.params.id; const project = await Project.findOne({ _id: projectId }); if (!project) { return res.status(404).json({ message: 'Project not found' }); } if (!(0, auth_1.isProjectMember)(project, auth.userId)) { return res.status(403).json({ message: 'Unauthorized project access' }); } res.json({ project: { ...project, id: project._id || project.id, _id: undefined }, message: 'Project fetched successfully' }); } catch (err) { res.status(500).json({ message: 'Failed to fetch project', details: err.message }); } }); router.patch('/projects/:id', async (req, res) => { try { const auth = req.auth; if (auth.role !== 'admin' && auth.role !== 'editor') { return res.status(403).json({ message: 'Permission denied' }); } const projectId = req.params.id; const updates = req.body; const project = await Project.findOne({ _id: projectId }); if (!project) { return res.status(404).json({ message: 'Project not found' }); } if (!updates || typeof updates !== 'object') { return res.status(400).json({ message: 'Missing updates payload' }); } if (!(0, auth_1.isProjectMember)(project, auth.userId)) { return res.status(403).json({ message: 'Unauthorized project access' }); } const updated = await Project.update({ _id: projectId }, updates); if (!updated) { return res.status(404).json({ message: 'Project not found or not updated' }); } const allProjects = await Project.find({}); const projects = allProjects .filter(project => { const isMember = project.members?.some((m) => m.userId?.toString() === auth.userId?.toString()); return isMember; // Only include projects where the user is a member }) .map(project => mapProjectToResponseFormat(project, auth.userId)); res.status(200).json({ success: true, projects: projects, projectId: updated._id || updated.id, message: 'Project updated successfully' }); } catch (err) { res.status(500).json({ message: 'Failed to update project', details: err.message }); } }); router.delete('/projects/:id', async (req, res) => { try { const auth = req.auth; const projectId = req.params.id; const project = await Project.findOne({ _id: projectId }); if (!project) { return res.status(404).json({ message: 'Project not found' }); } if (!(0, auth_1.isProjectMember)(project, auth.userId)) { return res.status(403).json({ message: 'Unauthorized project access' }); } await Project.useDbType(project.dbType).delete({ _id: projectId }); const allProjects = await Project.find({}); const projects = allProjects .filter(p => { const isMember = p.members?.some((m) => m.userId?.toString() === auth.userId?.toString()); return isMember; // Only include projects where the user is a member }) .map(p => mapProjectToResponseFormat(p, auth.userId)); res.status(200).json({ success: true, projects: projects, message: 'Project deleted successfully' }); } catch (err) { res.status(500).json({ message: 'Failed to delete project', details: err.message }); } }); router.patch('/projects/:id/archive', async (req, res) => { try { const auth = req.auth; const projectId = req.params.id; const project = await Project.findOne({ _id: projectId }); if (!project || !(0, auth_1.isProjectMember)(project, auth.userId)) { return res.status(403).json({ message: 'Unauthorized project access' }); } if (project.dbType === 'sql') { const connection = (0, connectionManager_1.getConnection)(config.databases?.find(db => db.main)?.id || '').client; await sql_1.sqlAdapter.update(connection, 'project_members', { projectId: projectId, userId: auth.userId }, { archived: true, archivedBy: auth.userId, archivedAt: new Date() }); } else { const memberIndex = project.members.findIndex((member) => member.userId === auth.userId); if (memberIndex === -1) { return res.status(403).json({ message: 'Unauthorized project access' }); } project.members[memberIndex].archived = true; project.members[memberIndex].archivedBy = auth.userId; project.members[memberIndex].archivedAt = new Date(); await Project.update({ _id: projectId }, { members: project.members }); } // Re-fetch all projects for the user to ensure the list is up-to-date const allProjects = await Project.find({}); const projects = allProjects .filter(project => { const isMember = project.members?.some((m) => m.userId?.toString() === auth.userId?.toString()); return isMember; // Only include projects where the user is a member }) .map(project => mapProjectToResponseFormat(project, auth.userId)); res.status(200).json({ success: true, projects: projects, message: 'Project archived successfully' }); } catch (err) { res.status(500).json({ message: 'Failed to archive project', details: err.message }); } }); router.patch('/projects/:id/unarchive', async (req, res) => { try { const auth = req.auth; const projectId = req.params.id; const project = await Project.findOne({ _id: projectId }); if (!project || !(0, auth_1.isProjectMember)(project, auth.userId)) { return res.status(403).json({ message: 'Unauthorized project access' }); } if (project.dbType === 'sql') { const connection = (0, connectionManager_1.getConnection)(config.databases?.find(db => db.main)?.id || '').client; await sql_1.sqlAdapter.update(connection, 'project_members', { projectId: projectId, userId: auth.userId }, { archived: false, archivedBy: null, archivedAt: null }); } else { const memberIndex = project.members.findIndex((member) => member.userId === auth.userId); if (memberIndex === -1) { return res.status(403).json({ message: 'Unauthorized project access' }); } project.members[memberIndex].archived = false; project.members[memberIndex].archivedBy = null; project.members[memberIndex].archivedAt = null; await Project.update({ _id: projectId }, { members: project.members }); } // Re-fetch all projects for the user to ensure the list is up-to-date const allProjects = await Project.find({}); const projects = allProjects .filter(project => { const isMember = project.members?.some((m) => m.userId?.toString() === auth.userId?.toString()); return isMember; // Only include projects where the user is a member }) .map(project => mapProjectToResponseFormat(project, auth.userId)); res.status(200).json({ success: true, projects: projects, message: 'Project unarchived successfully' }); } catch (err) { res.status(500).json({ message: 'Failed to unarchive project', details: err.message }); } }); router.get('/projects/:id/members', async (req, res) => { try { const auth = req.auth; const projectId = req.params.id; const project = await Project.findOne({ _id: projectId }); if (!project) { return res.status(404).json({ message: 'Project not found' }); } if (!(0, auth_1.isProjectMember)(project, auth.userId)) { return res.status(403).json({ message: 'Unauthorized project access' }); } const mainDb = config.databases?.find(db => db.main); if (!mainDb) { return res.status(500).json({ message: 'Main database not configured' }); } const userDbType = mainDb.type; const User = (0, manager_1.getModel)('users', userDbType); const membersWithUsernames = await Promise.all(project.members.map(async (member) => { const user = await User.findOne({ _id: member.userId }); return { userId: member.userId, username: user ? user.username : 'Unknown', role: member.role, profilePic: user ? user.profilePic : '' }; })); res.json({ members: membersWithUsernames, message: 'Project members fetched successfully' }); } catch (err) { res.status(500).json({ message: 'Failed to fetch project members', details: err.message }); } }); router.post('/projects/:id/image', async (req, res) => { try { const auth = req.auth; if (auth.role !== 'admin' && auth.role !== 'editor') { return res.status(403).json({ message: 'Permission denied' }); } const projectId = req.params.id; const { imageUrl } = req.body; if (!projectId || !imageUrl) { return res.status(400).json({ message: 'Missing projectId or imageUrl' }); } const project = await Project.findOne({ _id: projectId }); if (!project) { return res.status(404).json({ message: 'Project not found' }); } if (!(0, auth_1.isProjectMember)(project, auth.userId)) { return res.status(403).json({ message: 'Unauthorized project access' }); } const updatedProject = await Project.update({ _id: projectId }, { image: imageUrl }); if (!updatedProject) { return res.status(404).json({ message: 'Project not found or not updated' }); } res.status(200).json({ success: true, project: { ...updatedProject, id: updatedProject._id || updatedProject.id, _id: undefined }, message: 'Project image updated successfully' }); } catch (err) { res.status(500).json({ message: 'Failed to update project image', details: err.message }); } }); router.patch('/projects/:id/origins', async (req, res) => { try { const auth = req.auth; if (auth.role !== 'admin' && auth.role !== 'editor') { return res.status(403).json({ message: 'Permission denied' }); } const projectId = req.params.id; const { origins } = req.body; const project = await Project.findOne({ _id: projectId }); if (!project) { return res.status(404).json({ message: 'Project not found' }); } if (!(0, auth_1.isProjectMember)(project, auth.userId)) { return res.status(403).json({ message: 'Unauthorized project access' }); } const updated = await Project.update({ _id: projectId }, { allowedOrigin: origins }); if (!updated) { return res.status(404).json({ message: 'Project not found or not updated' }); } res.status(200).json({ success: true, project: updated, message: 'Project origins updated successfully' }); } catch (err) { res.status(500).json({ message: 'Failed to update project origins', details: err.message }); } }); return router; }