From 1e16e179b017792037eb29b7eeb51242cb2362cc Mon Sep 17 00:00:00 2001 From: Eric Doughty-Papassideris Date: Sun, 15 Sep 2024 00:03:49 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20backend=20cli:=20add=20editing=5Fse?= =?UTF-8?q?ssion=20list=20viewer=20command=20(and=20minor=20instanceId=20f?= =?UTF-8?q?ixes)=20(#525)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/cli/cmds/editing_session_cmds/list.ts | 54 +++++++++++++++++++ .../services/documents/entities/drive-file.ts | 12 +++-- .../src/services/documents/services/index.ts | 2 + 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 tdrive/backend/node/src/cli/cmds/editing_session_cmds/list.ts diff --git a/tdrive/backend/node/src/cli/cmds/editing_session_cmds/list.ts b/tdrive/backend/node/src/cli/cmds/editing_session_cmds/list.ts new file mode 100644 index 00000000..98c4bd48 --- /dev/null +++ b/tdrive/backend/node/src/cli/cmds/editing_session_cmds/list.ts @@ -0,0 +1,54 @@ +import yargs from "yargs"; + +import runWithPlatform from "../../lib/run-with-platform"; +import { TdrivePlatform } from "../../../core/platform/platform"; +import { DatabaseServiceAPI } from "../../../core/platform/services/database/api"; +import { + DriveFile, + EditingSessionKeyFormat, + TYPE, +} from "../../../services/documents/entities/drive-file"; + +async function report(platform: TdrivePlatform) { + const drivesRepo = await platform + .getProvider("database") + .getRepository(TYPE, DriveFile); + const editedFiled = (await drivesRepo.find({ editing_session_key: { $ne: null } })).getEntities(); + console.error("DriveFiles with non null editing_session_key (url encoded):"); + console.error(""); + editedFiled.forEach(dfile => { + console.error(`- ${dfile.name} (${dfile.id}) has key:`); + const parsed = EditingSessionKeyFormat.parse(dfile.editing_session_key); + console.error(` - URL encoded: ${encodeURIComponent(dfile.editing_session_key)}`); + console.error(` - applicationId: ${parsed.applicationId}`); + console.error(` - companyId: ${parsed.companyId}`); + console.error(` - instanceId: ${parsed.instanceId}`); + console.error( + ` - userId: ${parsed.userId} (${ + parsed.userId === dfile.creator ? "same as creator ID" : "not the creator" + })`, + ); + console.error( + ` - timestamp: ${parsed.timestamp.toISOString()} (${Math.floor( + (new Date().getTime() - parsed.timestamp.getTime()) / 1000, + )}s ago)`, + ); + }); + if (!editedFiled.length) console.error(" (no DriveFile currently has an editing_session_key)"); +} + +const command: yargs.CommandModule = { + command: "list", + describe: ` + List current DriveFile items that have an editing_session_key set + `.trim(), + builder: {}, + handler: async _argv => { + await runWithPlatform("editing_session list", async ({ spinner: _spinner, platform }) => { + console.error("\n"); + await report(platform); + console.error("\n"); + }); + }, +}; +export default command; diff --git a/tdrive/backend/node/src/services/documents/entities/drive-file.ts b/tdrive/backend/node/src/services/documents/entities/drive-file.ts index e4e029a5..5a793abc 100644 --- a/tdrive/backend/node/src/services/documents/entities/drive-file.ts +++ b/tdrive/backend/node/src/services/documents/entities/drive-file.ts @@ -135,7 +135,8 @@ const OnlyOfficeSafeDocKeyBase64 = { }, }; -function checkFieldValue(field: string, value: string) { +function checkFieldValue(field: string, value: string, required: boolean = true) { + if (!required && !value) return; if (!/^[0-9a-zA-Z_-]+$/m.test(value)) throw new Error( `Invalid ${field} value (${JSON.stringify( @@ -143,7 +144,12 @@ function checkFieldValue(field: string, value: string) { )}). Must be short and only alpha numeric or '_' and '-'`, ); } -/** Reference implementation for generating then parsing the {@link DriveFile.editing_session_key} field */ +/** + * Reference implementation for generating then parsing the {@link DriveFile.editing_session_key} field. + * + * Fields should be explicit, `instanceId` is for the case when we have multiple + * clients + */ export const EditingSessionKeyFormat = { // OnlyOffice key limits: 128 chars, [0-9a-zA-Z.=_-] // See https://api.onlyoffice.com/editors/config/document#key @@ -161,7 +167,7 @@ export const EditingSessionKeyFormat = { overrideTimeStamp?: Date, ) { checkFieldValue("applicationId", applicationId); - checkFieldValue("instanceId", instanceId); + checkFieldValue("instanceId", instanceId, false); const isoUTCDateNoSpecialCharsNoMS = (overrideTimeStamp ?? new Date()) .toISOString() .replace(/\..+$/, "") diff --git a/tdrive/backend/node/src/services/documents/services/index.ts b/tdrive/backend/node/src/services/documents/services/index.ts index cf8be32a..89027fc2 100644 --- a/tdrive/backend/node/src/services/documents/services/index.ts +++ b/tdrive/backend/node/src/services/documents/services/index.ts @@ -959,6 +959,8 @@ export class DocumentsService { * with only that key provided. * @param id DriveFile ID of the document to begin editing * @param editorApplicationId Editor/Application/Plugin specific identifier + * @param appInstanceId For that `editorApplicationId` a unique identifier + * when multiple instances are running. Unused today. * @param context * @returns An object in the format `{}` with the unique identifier for the * editing session