68 lines
2.5 KiB
TypeScript
68 lines
2.5 KiB
TypeScript
import { Router } from 'express';
|
|
import { projects, projectMembers } from '../db';
|
|
import { requireAuth } from '../middleware/auth';
|
|
import { createProjectStorage } from '../storage';
|
|
import { isOwner, canView, getMemberRole } from '../projectAccess';
|
|
|
|
const router = Router();
|
|
router.use( requireAuth );
|
|
|
|
router.get( '/', ( req, res ) =>
|
|
{
|
|
const user = req.user!;
|
|
const visible = projects.all().filter( p =>
|
|
{
|
|
if ( isOwner( p, user ) ) return true;
|
|
return getMemberRole( projectMembers.forProject( p.id ), user ) !== null;
|
|
} );
|
|
res.json( visible );
|
|
} );
|
|
|
|
router.post( '/', ( req, res ) =>
|
|
{
|
|
const { name } = req.body as { name?: string };
|
|
if ( !name ) { res.status( 400 ).json( { error: 'Name required' } ); return; }
|
|
const project = projects.create( { name, owner_id: req.user!.userId } );
|
|
createProjectStorage( project.id );
|
|
res.json( project );
|
|
} );
|
|
|
|
router.delete( '/:id', ( req, res ) =>
|
|
{
|
|
const project = projects.findById( req.params.id );
|
|
if ( !project ) { res.status( 404 ).json( { error: 'Not found' } ); return; }
|
|
if ( !isOwner( project, req.user! ) ) { res.status( 403 ).json( { error: 'Forbidden' } ); return; }
|
|
projects.delete( req.params.id );
|
|
res.json( { ok: true } );
|
|
} );
|
|
|
|
router.get( '/:id/members', ( req, res ) =>
|
|
{
|
|
const project = projects.findById( req.params.id );
|
|
if ( !project ) { res.status( 404 ).json( { error: 'Not found' } ); return; }
|
|
const members = projectMembers.forProject( req.params.id );
|
|
if ( !canView( project, members, req.user! ) ) { res.status( 403 ).json( { error: 'Forbidden' } ); return; }
|
|
res.json( members );
|
|
} );
|
|
|
|
router.post( '/:id/members', ( req, res ) =>
|
|
{
|
|
const project = projects.findById( req.params.id );
|
|
if ( !project ) { res.status( 404 ).json( { error: 'Not found' } ); return; }
|
|
if ( !isOwner( project, req.user! ) ) { res.status( 403 ).json( { error: 'Forbidden' } ); return; }
|
|
const { email, role } = req.body as { email?: string; role?: string };
|
|
if ( !email ) { res.status( 400 ).json( { error: 'email required' } ); return; }
|
|
res.json( projectMembers.add( { project_id: req.params.id, member_type: 'user', member_id: email, role: role ?? 'viewer' } ) );
|
|
} );
|
|
|
|
router.delete( '/:id/members/:memberId', ( req, res ) =>
|
|
{
|
|
const project = projects.findById( req.params.id );
|
|
if ( !project ) { res.status( 404 ).json( { error: 'Not found' } ); return; }
|
|
if ( !isOwner( project, req.user! ) ) { res.status( 403 ).json( { error: 'Forbidden' } ); return; }
|
|
projectMembers.remove( req.params.memberId );
|
|
res.json( { ok: true } );
|
|
} );
|
|
|
|
export default router;
|