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
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import type { ConfirmBookingResponse } from '~~/shared/booking'
|
|
|
|
import { requireBookingManager } from '../../../../utils/auth'
|
|
import { confirmBookingByConfirmationToken, getBookingByConfirmationToken, getBookingInventorySummary } from '../../../../utils/booking-repository'
|
|
import { getRequiredRouteParam, httpError } from '../../../../utils/http'
|
|
import { sendBookingTicketReceiptViaWhatsApp } from '../../../../utils/whatsapp'
|
|
|
|
export default defineEventHandler(async (event): Promise<ConfirmBookingResponse> => {
|
|
const token = getRequiredRouteParam(event, 'token', 'Confirmation token')
|
|
const existingBooking = await getBookingByConfirmationToken(token, { includeTransactionDocument: true })
|
|
|
|
if (!existingBooking) {
|
|
httpError(404, 'Booking not found')
|
|
}
|
|
|
|
await requireBookingManager(event, existingBooking)
|
|
|
|
if (existingBooking.status === 'confirmed') {
|
|
return {
|
|
booking: existingBooking,
|
|
alreadyConfirmed: true,
|
|
ticketReceiptWhatsApp: {
|
|
sent: false,
|
|
skipped: true,
|
|
recipientPhone: existingBooking.customerPhone,
|
|
apiRecipientPhone: existingBooking.customerPhone.replace(/\D/g, ''),
|
|
error: 'Booking was already confirmed earlier.'
|
|
}
|
|
}
|
|
}
|
|
|
|
const summary = await getBookingInventorySummary()
|
|
|
|
if (summary.leftSeats !== null && existingBooking.seatCount > summary.leftSeats) {
|
|
httpError(409, 'Not enough capacity left to confirm this booking')
|
|
}
|
|
|
|
const booking = await confirmBookingByConfirmationToken(token)
|
|
|
|
if (!booking) {
|
|
httpError(404, 'Booking not found')
|
|
}
|
|
|
|
const ticketReceiptWhatsApp = await sendBookingTicketReceiptViaWhatsApp(event, booking)
|
|
const refreshedBooking = await getBookingByConfirmationToken(token, { includeTransactionDocument: true })
|
|
|
|
return {
|
|
booking: refreshedBooking || booking,
|
|
alreadyConfirmed: false,
|
|
ticketReceiptWhatsApp
|
|
}
|
|
})
|