Secure API endpoints with requireBookingManager authorization check Update confirmation page to prompt for login if unauthorized Add safe redirect handling to login and guest middleware
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import { sendStream, setHeader } from 'h3'
|
|
|
|
import { requireBookingManager } from '../../../../utils/auth'
|
|
import { getBookingByConfirmationToken, getBookingTransactionDocumentByConfirmationToken } from '../../../../utils/booking-repository'
|
|
import { getRequiredRouteParam, httpError } from '../../../../utils/http'
|
|
import {
|
|
getSafeDownloadName,
|
|
getTransactionDocumentFile
|
|
} from '../../../../utils/transaction-documents'
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const token = getRequiredRouteParam(event, 'token', 'Confirmation token')
|
|
const booking = await getBookingByConfirmationToken(token)
|
|
|
|
if (!booking) {
|
|
httpError(404, 'Booking not found')
|
|
}
|
|
|
|
await requireBookingManager(event, booking)
|
|
|
|
const document = await getBookingTransactionDocumentByConfirmationToken(token)
|
|
|
|
if (!document) {
|
|
httpError(404, 'Transaction document not found')
|
|
}
|
|
|
|
const file = await getTransactionDocumentFile(document.storageName)
|
|
const downloadName = getSafeDownloadName(document.originalName)
|
|
|
|
setHeader(event, 'content-type', document.mimeType)
|
|
setHeader(event, 'content-length', String(file.size))
|
|
setHeader(event, 'content-disposition', `attachment; filename="${downloadName}"`)
|
|
setHeader(event, 'x-content-type-options', 'nosniff')
|
|
setHeader(event, 'cache-control', 'private, no-store')
|
|
setHeader(event, 'content-security-policy', 'sandbox')
|
|
|
|
return sendStream(event, file.stream)
|
|
})
|