From 5aa7b42f8b8dc10eff0a75fe179e7f7024a98d10 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Wed, 20 Sep 2023 20:27:50 -0400 Subject: [PATCH] fix: Cannot read properties of undefined (reading 'id') --- server/collaboration/ConnectionLimitExtension.ts | 11 ++++------- server/collaboration/LoggerExtension.ts | 7 ++++--- server/collaboration/MetricsExtension.ts | 15 +++++++++++---- server/collaboration/PersistenceExtension.ts | 12 +++++++++--- server/collaboration/ViewsExtension.ts | 11 ++++++++++- server/collaboration/types.ts | 7 +++++++ 6 files changed, 45 insertions(+), 18 deletions(-) create mode 100644 server/collaboration/types.ts diff --git a/server/collaboration/ConnectionLimitExtension.ts b/server/collaboration/ConnectionLimitExtension.ts index 778f71098..3bb4e4017 100644 --- a/server/collaboration/ConnectionLimitExtension.ts +++ b/server/collaboration/ConnectionLimitExtension.ts @@ -7,6 +7,7 @@ import env from "@server/env"; import Logger from "@server/logging/Logger"; import { trace } from "@server/logging/tracing"; import { TooManyConnections } from "./CloseEvents"; +import { withContext } from "./types"; @trace() export class ConnectionLimitExtension implements Extension { @@ -19,9 +20,7 @@ export class ConnectionLimitExtension implements Extension { * onDisconnect hook * @param data The disconnect payload */ - onDisconnect(data: onDisconnectPayload) { - const { documentName, socketId } = data; - + onDisconnect({ documentName, socketId }: withContext) { const connections = this.connectionsByDocument.get(documentName); if (connections) { connections.delete(socketId); @@ -45,9 +44,7 @@ export class ConnectionLimitExtension implements Extension { * onConnect hook * @param data The connect payload */ - onConnect(data: onConnectPayload) { - const { documentName } = data; - + onConnect({ documentName, socketId }: withContext) { const connections = this.connectionsByDocument.get(documentName) || new Set(); if (connections?.size >= env.COLLABORATION_MAX_CLIENTS_PER_DOCUMENT) { @@ -60,7 +57,7 @@ export class ConnectionLimitExtension implements Extension { return Promise.reject(TooManyConnections); } - connections.add(data.socketId); + connections.add(socketId); this.connectionsByDocument.set(documentName, connections); Logger.debug( diff --git a/server/collaboration/LoggerExtension.ts b/server/collaboration/LoggerExtension.ts index 18ee06bc7..473f2a464 100644 --- a/server/collaboration/LoggerExtension.ts +++ b/server/collaboration/LoggerExtension.ts @@ -5,19 +5,20 @@ import { Extension, } from "@hocuspocus/server"; import Logger from "@server/logging/Logger"; +import { withContext } from "./types"; export default class LoggerExtension implements Extension { - async onLoadDocument(data: onLoadDocumentPayload) { + async onLoadDocument(data: withContext) { Logger.info("multiplayer", `Loaded document "${data.documentName}"`, { userId: data.context.user?.id, }); } - async onConnect(data: onConnectPayload) { + async onConnect(data: withContext) { Logger.info("multiplayer", `New connection to "${data.documentName}"`); } - async onDisconnect(data: onDisconnectPayload) { + async onDisconnect(data: withContext) { Logger.info("multiplayer", `Closed connection to "${data.documentName}"`, { userId: data.context.user?.id, }); diff --git a/server/collaboration/MetricsExtension.ts b/server/collaboration/MetricsExtension.ts index 8f5d06b20..b5ee6c26c 100644 --- a/server/collaboration/MetricsExtension.ts +++ b/server/collaboration/MetricsExtension.ts @@ -6,9 +6,13 @@ import { Extension, } from "@hocuspocus/server"; import Metrics from "@server/logging/Metrics"; +import { withContext } from "./types"; export default class MetricsExtension implements Extension { - async onLoadDocument({ documentName, instance }: onLoadDocumentPayload) { + async onLoadDocument({ + documentName, + instance, + }: withContext) { Metrics.increment("collaboration.load_document", { documentName, }); @@ -24,7 +28,7 @@ export default class MetricsExtension implements Extension { }); } - async onConnect({ documentName, instance }: onConnectPayload) { + async onConnect({ documentName, instance }: withContext) { Metrics.increment("collaboration.connect", { documentName, }); @@ -38,7 +42,10 @@ export default class MetricsExtension implements Extension { ); } - async onDisconnect({ documentName, instance }: onDisconnectPayload) { + async onDisconnect({ + documentName, + instance, + }: withContext) { Metrics.increment("collaboration.disconnect", { documentName, }); @@ -52,7 +59,7 @@ export default class MetricsExtension implements Extension { ); } - async onStoreDocument({ documentName }: onChangePayload) { + async onStoreDocument({ documentName }: withContext) { Metrics.increment("collaboration.change", { documentName, }); diff --git a/server/collaboration/PersistenceExtension.ts b/server/collaboration/PersistenceExtension.ts index 93e7ce66b..6b847d15a 100644 --- a/server/collaboration/PersistenceExtension.ts +++ b/server/collaboration/PersistenceExtension.ts @@ -11,6 +11,7 @@ import Document from "@server/models/Document"; import ProsemirrorHelper from "@server/models/helpers/ProsemirrorHelper"; import { sequelize } from "@server/storage/database"; import documentCollaborativeUpdater from "../commands/documentCollaborativeUpdater"; +import { withContext } from "./types"; @trace() export default class PersistenceExtension implements Extension { @@ -20,7 +21,10 @@ export default class PersistenceExtension implements Extension { */ documentCollaboratorIds = new Map>(); - async onLoadDocument({ documentName, ...data }: onLoadDocumentPayload) { + async onLoadDocument({ + documentName, + ...data + }: withContext) { const [, documentId] = documentName.split("."); const fieldName = "default"; @@ -67,14 +71,16 @@ export default class PersistenceExtension implements Extension { }); } - async onChange({ context, documentName }: onChangePayload) { + async onChange({ context, documentName }: withContext) { Logger.debug( "multiplayer", `${context.user?.name} changed ${documentName}` ); const state = this.documentCollaboratorIds.get(documentName) ?? new Set(); - state.add(context.user?.id); + if (context.user) { + state.add(context.user.id); + } this.documentCollaboratorIds.set(documentName, state); } diff --git a/server/collaboration/ViewsExtension.ts b/server/collaboration/ViewsExtension.ts index b2b5c054e..fc4096779 100644 --- a/server/collaboration/ViewsExtension.ts +++ b/server/collaboration/ViewsExtension.ts @@ -7,6 +7,7 @@ import { Minute } from "@shared/utils/time"; import Logger from "@server/logging/Logger"; import { trace } from "@server/logging/tracing"; import { View } from "@server/models"; +import { withContext } from "./types"; @trace() export class ViewsExtension implements Extension { @@ -21,7 +22,15 @@ export class ViewsExtension implements Extension { * * @param data The change payload */ - async onChange({ documentName, context, socketId }: onChangePayload) { + async onChange({ + documentName, + context, + socketId, + }: withContext) { + if (!context.user) { + return; + } + const lastUpdate = this.lastViewBySocket.get(socketId); const [, documentId] = documentName.split("."); diff --git a/server/collaboration/types.ts b/server/collaboration/types.ts new file mode 100644 index 000000000..cef782fed --- /dev/null +++ b/server/collaboration/types.ts @@ -0,0 +1,7 @@ +import type { User } from "@server/models"; + +export type withContext = Omit & { + context: { + user?: User; + }; +};