diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/BookingFlow.kt b/src/main/kotlin/com/android/trisolarisserver/controller/BookingFlow.kt index 0de2835..90a2912 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/BookingFlow.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/BookingFlow.kt @@ -32,6 +32,7 @@ import com.android.trisolarisserver.repo.PropertyRepo import com.android.trisolarisserver.repo.RoomRepo import com.android.trisolarisserver.repo.RoomStayRepo import com.android.trisolarisserver.security.MyPrincipal +import jakarta.servlet.http.HttpServletResponse import org.springframework.http.HttpStatus import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.transaction.annotation.Transactional @@ -248,7 +249,8 @@ class BookingFlow( fun streamBooking( @PathVariable propertyId: UUID, @PathVariable bookingId: UUID, - @AuthenticationPrincipal principal: MyPrincipal? + @AuthenticationPrincipal principal: MyPrincipal?, + response: HttpServletResponse ): org.springframework.web.servlet.mvc.method.annotation.SseEmitter { requireRole( propertyAccess, @@ -261,6 +263,7 @@ class BookingFlow( Role.FINANCE ) requireBooking(propertyId, bookingId) + prepareSse(response) return bookingEvents.subscribe(propertyId, bookingId) } @@ -725,4 +728,10 @@ class BookingFlow( return true } + private fun prepareSse(response: HttpServletResponse) { + response.setHeader("Cache-Control", "no-cache") + response.setHeader("Connection", "keep-alive") + response.setHeader("X-Accel-Buffering", "no") + } + } diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/GuestDocuments.kt b/src/main/kotlin/com/android/trisolarisserver/controller/GuestDocuments.kt index c892d30..2e58de7 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/GuestDocuments.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/GuestDocuments.kt @@ -138,6 +138,7 @@ class GuestDocuments( ): org.springframework.web.servlet.mvc.method.annotation.SseEmitter { requireRole(propertyAccess, propertyId, principal, Role.ADMIN, Role.MANAGER) response.setHeader("Cache-Control", "no-cache") + response.setHeader("Connection", "keep-alive") response.setHeader("X-Accel-Buffering", "no") return guestDocumentEvents.subscribe(propertyId, guestId) } diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/RazorpayQrPayments.kt b/src/main/kotlin/com/android/trisolarisserver/controller/RazorpayQrPayments.kt index 09d9ca4..afcaad9 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/RazorpayQrPayments.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/RazorpayQrPayments.kt @@ -15,6 +15,7 @@ import com.android.trisolarisserver.repo.RazorpaySettingsRepo import com.android.trisolarisserver.repo.RazorpayWebhookLogRepo import com.android.trisolarisserver.security.MyPrincipal import com.fasterxml.jackson.databind.ObjectMapper +import jakarta.servlet.http.HttpServletResponse import org.springframework.http.HttpEntity import org.springframework.http.HttpHeaders import org.springframework.http.HttpMethod @@ -267,12 +268,20 @@ class RazorpayQrPayments( @PathVariable propertyId: UUID, @PathVariable bookingId: UUID, @PathVariable qrId: String, - @AuthenticationPrincipal principal: MyPrincipal? + @AuthenticationPrincipal principal: MyPrincipal?, + response: HttpServletResponse ): SseEmitter { requireRole(propertyAccess, propertyId, principal, Role.ADMIN, Role.MANAGER, Role.STAFF) + prepareSse(response) return qrEvents.subscribe(propertyId, qrId) } + private fun prepareSse(response: HttpServletResponse) { + response.setHeader("Cache-Control", "no-cache") + response.setHeader("Connection", "keep-alive") + response.setHeader("X-Accel-Buffering", "no") + } + @GetMapping("/qr") fun listQr( @PathVariable propertyId: UUID, diff --git a/src/main/kotlin/com/android/trisolarisserver/controller/Rooms.kt b/src/main/kotlin/com/android/trisolarisserver/controller/Rooms.kt index f6bdd16..6c902c5 100644 --- a/src/main/kotlin/com/android/trisolarisserver/controller/Rooms.kt +++ b/src/main/kotlin/com/android/trisolarisserver/controller/Rooms.kt @@ -22,6 +22,7 @@ import com.android.trisolarisserver.models.room.Room import com.android.trisolarisserver.models.room.RatePlan import com.android.trisolarisserver.models.property.Role import com.android.trisolarisserver.security.MyPrincipal +import jakarta.servlet.http.HttpServletResponse import org.springframework.http.HttpStatus import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.web.bind.annotation.GetMapping @@ -109,10 +110,12 @@ class Rooms( @GetMapping("/board/stream") fun roomBoardStream( @PathVariable propertyId: UUID, - @AuthenticationPrincipal principal: MyPrincipal? + @AuthenticationPrincipal principal: MyPrincipal?, + response: HttpServletResponse ): SseEmitter { requirePrincipal(principal) propertyAccess.requireMember(propertyId, principal!!.userId) + prepareSse(response) return roomBoardEvents.subscribe(propertyId) } @@ -442,6 +445,12 @@ class Rooms( .groupBy { it.room.id ?: throw IllegalStateException("Room id is null") } .mapValues { (_, cards) -> cards.maxBy { it.expiresAt }.expiresAt } } + + private fun prepareSse(response: HttpServletResponse) { + response.setHeader("Cache-Control", "no-cache") + response.setHeader("Connection", "keep-alive") + response.setHeader("X-Accel-Buffering", "no") + } } private fun Room.toRoomResponse(tempCardExpiresAt: OffsetDateTime? = null): RoomResponse {