Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion backend/src/controllers/team.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import { Request, Response } from 'express';
import teamSessionStore, { normalizeTeamSessionCode, isValidTeamRepo } from '../services/teamSessions.js';

export const createTeamSession = async (req: Request, res: Response): Promise<any> => {
const { repo } = req.body;
// `|| {}` rather than a bare destructure. express.json() leaves req.body
// undefined when the Content-Type is not JSON, and destructuring undefined
// throws a TypeError before the validation below can return a clean 400.
// Carried over from the duplicate handler in system.routes.ts, which had
// this guard where the controller did not -- removing that handler without
// porting it would have turned a 400 into a 500.
const { repo } = req.body || {};

if (!isValidTeamRepo(repo)) {
return res.status(400).json({ error: 'Valid repo object with owner, name, and fullName is required' });
Expand Down
25 changes: 0 additions & 25 deletions backend/src/routes/system.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
recordMonitoringEvent,
} from '../services/monitoringService.js';
import teamSessionStore, {
isValidTeamRepo,
normalizeTeamSessionCode,
} from '../services/teamSessions.js';
import { getReadinessPayload } from '../utils/runtimeConfig.js';
Expand Down Expand Up @@ -91,30 +90,6 @@ export const createSystemRouter = (): Router => {
});
});

router.post('/team-sessions/create', requireAccessToken, async (req: Request, res: Response): Promise<any> => {
const { repo } = req.body || {};

if (!isValidTeamRepo(repo)) {
return res.status(400).json({ error: 'Valid repository details are required' });
}

// The host identity is taken from the authenticated session, never from the
// request body. A `createdBy` sent by the client is ignored: it is the one
// field that decides which name and login every joining participant sees
// attributed to this room, so accepting it from the caller lets any
// authenticated user host a session under someone else's identity.
const sessionUser = req.authSession?.user;
if (!sessionUser?.login) {
return res.status(403).json({ error: 'An authenticated user session is required to host a team session' });
}

const session = await teamSessionStore.createSession({
repo,
createdBy: { login: sessionUser.login, name: sessionUser.name || sessionUser.login },
});
res.json(session);
});

router.post('/team-sessions/join', async (req: Request, res: Response): Promise<any> => {
const code = normalizeTeamSessionCode(req.body?.code);

Expand Down
Loading