From 2e82ea3f0d7bfe5dc4144d687b331944eb760d1e Mon Sep 17 00:00:00 2001 From: Michael Wedl Date: Wed, 17 Apr 2024 07:29:05 +0200 Subject: [PATCH 1/2] Filter more selections --- frontend/src/utils/collab.ts | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/frontend/src/utils/collab.ts b/frontend/src/utils/collab.ts index 65ea799fc..fb3b12c59 100644 --- a/frontend/src/utils/collab.ts +++ b/frontend/src/utils/collab.ts @@ -187,25 +187,19 @@ export function useCollab(storeState: CollabStoreState) { v.sendUpdateTextThrottled.cancel(); } } - // Filter out invalid selections - for (const a of [storeState.awareness.self].concat(Object.values(storeState.awareness.other))) { - if (a.path && (msgData.path === a.path || msgData.path.startsWith(a.path + '.')) && a.selection) { - const text = get(storeState.data as Object, a.path); - if (typeof text !== 'string' || !a.selection.ranges.every(r => r.from >= 0 && r.to <= (text || '').length)) { - a.selection = undefined; - } - } - } // Update local state set(storeState.data as Object, msgData.path, msgData.value); + + removeInvalidSelections(msgData.path); } else if (msgData.type === CollabEventType.UPDATE_TEXT) { receiveUpdateText(msgData); } else if (msgData.type === CollabEventType.CREATE) { set(storeState.data as Object, msgData.path, msgData.value); } else if (msgData.type === CollabEventType.DELETE) { const pathParts = msgData.path.split('.'); - const parentList = get(storeState.data as Object, pathParts.slice(0, -1).join('.')); + const parentPath = pathParts.slice(0, -1).join('.'); + const parentList = get(storeState.data as Object, parentPath); const parentListIndex = Number.parseInt(pathParts.slice(-1)?.[0].startsWith('[') ? pathParts.slice(-1)[0].slice(1, -1) : undefined); if (Array.isArray(parentList) && !Number.isNaN(parentListIndex)) { @@ -213,6 +207,7 @@ export function useCollab(storeState: CollabStoreState) { } else { unset(storeState.data as Object, msgData.path); } + removeInvalidSelections(parentPath); } else if (msgData.type === CollabEventType.CONNECT) { if (msgData.client_id !== storeState.clientID) { // Add new client @@ -541,6 +536,18 @@ export function useCollab(storeState: CollabStoreState) { } } + function removeInvalidSelections(path?: string) { + // Filter out invalid selections + for (const a of [storeState.awareness.self].concat(Object.values(storeState.awareness.other))) { + if (a.path && (!path || path === a.path || path.startsWith(a.path + '.')) && a.selection) { + const text = get(storeState.data as Object, a.path); + if (typeof text !== 'string' || !a.selection.ranges.every(r => r.from >= 0 && r.to <= (text || '').length)) { + a.selection = undefined; + } + } + } + } + function onCollabEvent(event: any) { if (event.type === CollabEventType.UPDATE_KEY) { updateKey(event); From e4348f2ec28a1b58cb43db987454f4236af960e6 Mon Sep 17 00:00:00 2001 From: Michael Wedl Date: Wed, 17 Apr 2024 07:47:48 +0200 Subject: [PATCH 2/2] Fix user notes --- frontend/src/stores/project.ts | 16 +++++++++------- frontend/src/stores/usernotes.ts | 3 +-- frontend/src/utils/collab.ts | 6 +++--- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/frontend/src/stores/project.ts b/frontend/src/stores/project.ts index 8959accab..7f393cf3d 100644 --- a/frontend/src/stores/project.ts +++ b/frontend/src/stores/project.ts @@ -51,7 +51,11 @@ export const useProjectStore = defineStore('project', { // notes: ProjectNote[], getByIdSync: Promise | null, notesCollabState: CollabStoreState<{ notes: {[key: string]: ProjectNote}}>, - reportingCollabState: CollabStoreState<{ findings: {[key: string]: PentestFinding }, sections: {[key: string]: ReportSection } }>, + reportingCollabState: CollabStoreState<{ + project: {id: string, project_type: string, override_finding_order: boolean}, + findings: {[key: string]: PentestFinding }, + sections: {[key: string]: ReportSection } + }>, } }, }), @@ -102,9 +106,8 @@ export const useProjectStore = defineStore('project', { getByIdSync: null, notesCollabState: makeCollabStoreState({ websocketPath: `/ws/pentestprojects/${projectId}/notes/`, - initialData: { notes: {} }, - handleAdditionalWebSocketMessages: (msgData: any) => { - const collabState = this.data[projectId].notesCollabState; + initialData: { notes: {} as {[key: string]: ProjectNote} }, + handleAdditionalWebSocketMessages: (msgData: any, collabState) => { if (msgData.type === CollabEventType.SORT && msgData.path === 'notes') { for (const note of Object.values(collabState.data.notes)) { const no = msgData.sort.find((n: ProjectNote) => n.id === note.id); @@ -119,9 +122,8 @@ export const useProjectStore = defineStore('project', { }), reportingCollabState: makeCollabStoreState({ websocketPath: `/ws/pentestprojects/${projectId}/reporting/`, - initialData: { project: {}, findings: {}, sections: {} }, - handleAdditionalWebSocketMessages: (msgData: any) => { - const collabState = this.data[projectId].reportingCollabState; + initialData: { project: {} as any, findings: {} as {[key: string]: PentestFinding}, sections: {} as {[key: string]: ReportSection} }, + handleAdditionalWebSocketMessages: (msgData: any, collabState) => { if (msgData.type === CollabEventType.SORT && msgData.path === 'findings') { for (const finding of Object.values(collabState.data.findings)) { const fo = msgData.sort.find((n: PentestFinding) => n.id === finding.id); diff --git a/frontend/src/stores/usernotes.ts b/frontend/src/stores/usernotes.ts index 3567901ec..8c01db378 100644 --- a/frontend/src/stores/usernotes.ts +++ b/frontend/src/stores/usernotes.ts @@ -39,8 +39,7 @@ export const useUserNotesStore = defineStore('usernotes', { notesCollabState: makeCollabStoreState({ websocketPath: '/ws/pentestusers/self/notes/', initialData: { notes: {} as {[key: string]: UserNote} }, - handleAdditionalWebSocketMessages: (msgData: any) => { - const collabState = (this as any).notesCollabState; + handleAdditionalWebSocketMessages: (msgData: any, collabState) => { if (msgData.type === CollabEventType.SORT && msgData.path === 'notes') { for (const note of Object.values(collabState.data.notes) as UserNote[]) { const no = msgData.sort.find((n: UserNote) => n.id === note.id); diff --git a/frontend/src/utils/collab.ts b/frontend/src/utils/collab.ts index fb3b12c59..3178b37eb 100644 --- a/frontend/src/utils/collab.ts +++ b/frontend/src/utils/collab.ts @@ -43,7 +43,7 @@ export type CollabStoreState = { websocketPath: string; connectionError?: { error: any, message?: string }; websocketConnectionLostTimeout?: ReturnType; - handleAdditionalWebSocketMessages?: (event: any) => boolean; + handleAdditionalWebSocketMessages?: (event: any, collabState: CollabStoreState) => boolean; perPathState: Map; unconfirmedTextUpdates: TextUpdate[]; @@ -74,7 +74,7 @@ export type CollabStoreState = { export function makeCollabStoreState(options: { websocketPath: string, initialData: T, - handleAdditionalWebSocketMessages?: (event: any) => boolean + handleAdditionalWebSocketMessages?: (event: any, storeState: CollabStoreState) => boolean }): CollabStoreState { return { data: options.initialData, @@ -166,7 +166,7 @@ export function useCollab(storeState: CollabStoreState) { storeState.version = msgData.version; } - if (storeState.handleAdditionalWebSocketMessages?.(msgData)) { + if (storeState.handleAdditionalWebSocketMessages?.(msgData, storeState)) { // Already handled } else if (msgData.type === CollabEventType.INIT) { storeState.connectionState = CollabConnectionState.OPEN;