Stop throwing for event stream does not exists (#20008)

Fixes
https://twenty-v7.sentry.io/issues/7351816489/?environment=prod&environment=prod-eu&project=4507072499810304&query=is%3Aunresolved%20%21issue.type%3A%5Bperformance_consecutive_db_queries%2Cperformance_consecutive_http%2Cperformance_file_io_main_thread%2Cperformance_db_main_thread%2Cperformance_n_plus_one_db_queries%2Cperformance_n_plus_one_api_calls%2Cperformance_p95_endpoint_regression%2Cperformance_slow_db_query%2Cperformance_render_blocking_asset_span%2Cperformance_uncompressed_assets%2Cperformance_http_overhead%2Cperformance_large_http_payload%5D%20timesSeen%3A%3E10&referrer=issue-stream&sort=date

- When an SSE event stream already exists in Redis during a
reconnection, the server now checks if the caller is the rightful owner
(via isAuthorized) and destroys the stale stream before creating a fresh
one, instead of throwing an EVENT_STREAM_ALREADY_EXISTS error
- Unauthorized callers still receive the error, preserving the security
guard against hijacking
This commit is contained in:
Thomas Trompette
2026-04-23 15:22:09 +02:00
committed by GitHub
parent 992a7ca12f
commit d887fdc532
@@ -64,16 +64,31 @@ export class EventStreamResolver {
) {
const eventStreamChannelId = eventStreamIdToChannelId(eventStreamId);
const streamData = await this.eventStreamService.getStreamData(
const existingStreamData = await this.eventStreamService.getStreamData(
workspace.id,
eventStreamChannelId,
);
if (isDefined(streamData)) {
throw new EventStreamException(
'Event stream already exists',
EventStreamExceptionCode.EVENT_STREAM_ALREADY_EXISTS,
);
if (isDefined(existingStreamData)) {
const isAuthorized = await this.eventStreamService.isAuthorized({
streamData: existingStreamData,
authContext: {
userWorkspaceId,
apiKeyId: apiKey?.id,
},
});
if (!isAuthorized) {
throw new EventStreamException(
'Event stream already exists',
EventStreamExceptionCode.EVENT_STREAM_ALREADY_EXISTS,
);
}
await this.eventStreamService.destroyEventStream({
workspaceId: workspace.id,
eventStreamChannelId,
});
}
await this.eventStreamService.createEventStream({