Skip to content
This repository was archived by the owner on Apr 8, 2026. It is now read-only.

Commit 653d98d

Browse files
committed
feat(eocd): add endpoint to fetch EOCD for a game with access control
1 parent f43c13e commit 653d98d

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

src/controllers/GameController.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,43 @@ export class Games {
475475
handleError(res, error, 'Error fetching file metadata');
476476
}
477477
}
478+
479+
@httpGet('/:gameId/eocd', LoggedCheck.middleware)
480+
public async getEOCD(req: AuthenticatedRequest, res: Response) {
481+
const { gameId } = req.params;
482+
const userId = req.user.user_id;
483+
484+
try {
485+
const game = await this.gameService.getGame(gameId);
486+
if (!game) {
487+
return res.status(404).send({ message: 'Game not found' });
488+
}
489+
490+
const owns = (await this.gameService.userOwnsGame(gameId, userId)) || game.owner_id === userId;
491+
if (!owns) {
492+
return res.status(403).send({ message: 'Access denied' });
493+
}
494+
495+
const link = game.download_link;
496+
if (!link) {
497+
return res.status(404).send({ message: 'Download link not available' });
498+
}
499+
500+
// Fetch the last 22 bytes of the file (minimum EOCD size)
501+
const rangeHeader = 'bytes=-22';
502+
const fileRes = await fetch(link, { headers: { Range: rangeHeader } });
503+
504+
if (!fileRes.ok) {
505+
return res.status(fileRes.status).send({ message: 'Error fetching EOCD' });
506+
}
507+
508+
const buffer = await fileRes.arrayBuffer();
509+
res.setHeader('Content-Type', 'application/octet-stream');
510+
res.status(200).send(Buffer.from(buffer));
511+
} catch (error) {
512+
handleError(res, error, 'Error fetching EOCD');
513+
}
514+
}
478515
}
479516

480517

0 commit comments

Comments
 (0)