import { JwtAuthGuard, VerifiedScopeGuard } from "@cv/auth"; import { AuthorizationService, CV as CVEntity, CVService, User as DomainUser, } from "@cv/core"; import { FILE_STORAGE, type FileStorage } from "@cv/file-storage"; import { Controller, Get, Inject, NotFoundException, Param, Req, Res, UseGuards, } from "@nestjs/common"; import type { Response } from "express"; @Controller("api/cv") @UseGuards(JwtAuthGuard, VerifiedScopeGuard) export class PdfDownloadController { constructor( private readonly cvService: CVService, private readonly authorizationService: AuthorizationService, @Inject(FILE_STORAGE) private readonly storage: FileStorage, ) {} @Get(":id/pdf") async downloadPdf( @Req() req: { user: DomainUser }, @Param("id") id: string, @Res() res: Response, ): Promise { const cv = await this.cvService.findByIdOrFail(id); await this.authorizationService.canView(req.user, cv, CVEntity); const key = `${id}.pdf`; if (!(await this.storage.exists(key))) { throw new NotFoundException("PDF not yet available"); } const pdf = await this.storage.read(key); const safeTitle = cv.title.replace(/[^a-zA-Z0-9_\- ]/g, ""); res.set({ "Content-Type": "application/pdf", "Content-Disposition": `attachment; filename="${safeTitle}.pdf"`, "Content-Length": pdf.length.toString(), }); res.send(pdf); } }