diff --git a/tdrive/backend/node/src/services/documents/services/index.ts b/tdrive/backend/node/src/services/documents/services/index.ts index c8f08854..744b73f3 100644 --- a/tdrive/backend/node/src/services/documents/services/index.ts +++ b/tdrive/backend/node/src/services/documents/services/index.ts @@ -1075,6 +1075,8 @@ export class DocumentsService { * @param options Optional upload information from the request * @param keepEditing If `true`, the file will be saved as a new version, * and the DriveFile will keep its editing_session_key. If `true`, a file is required. + * @param userId When authentified by the root token of an application, this user + * will override the creator of this version * @param context */ updateEditing = async ( @@ -1082,8 +1084,12 @@ export class DocumentsService { file: MultipartFile, options: UploadOptions, keepEditing: boolean, + userId: string | null, context: CompanyExecutionContext, ) => { + //TODO rethink the locking stuff shouldn't be just forgotten + //TODO Make this accept even if missing and act ok about it, + // store to dump folder or such if (!context) { this.logger.error("invalid execution context"); return null; @@ -1092,14 +1098,22 @@ export class DocumentsService { this.logger.error("Invalid editing_session_key: " + JSON.stringify(editing_session_key)); throw new CrudException("Invalid editing_session_key", 400); } - - //TODO If the app is the "user" calling, set user to that from the parsed key try { const parsedKey = EditingSessionKeyFormat.parse(editing_session_key); context = { ...context, company: { id: parsedKey.companyId }, }; + + if (context.user.id === context.user.application_id && context.user.application_id) { + context = { + ...context, + user: { + ...context.user, + id: userId || parsedKey.userId, + }, + }; + } } catch (e) { this.logger.error( "Invalid editing_session_key value: " + JSON.stringify(editing_session_key), diff --git a/tdrive/backend/node/src/services/documents/web/controllers/documents.ts b/tdrive/backend/node/src/services/documents/web/controllers/documents.ts index a094f604..655e9a41 100644 --- a/tdrive/backend/node/src/services/documents/web/controllers/documents.ts +++ b/tdrive/backend/node/src/services/documents/web/controllers/documents.ts @@ -386,6 +386,7 @@ export class DocumentsController { null, null, false, + null, context, ); } catch (error) { @@ -401,7 +402,7 @@ export class DocumentsController { updateEditing = async ( request: FastifyRequest<{ Params: ItemRequestByEditingSessionKeyParams; - Querystring: { keepEditing?: string }; + Querystring: { keepEditing?: string; userId?: string }; Body: { item: Partial; version: Partial; @@ -430,6 +431,7 @@ export class DocumentsController { file, options, request.query.keepEditing == "true", + request.query.userId, context, ); } else { @@ -438,6 +440,7 @@ export class DocumentsController { null, null, true, + request.query.userId, context, ); } diff --git a/tdrive/backend/node/test/e2e/common/user-api.ts b/tdrive/backend/node/test/e2e/common/user-api.ts index 133a3eff..0ce15cde 100644 --- a/tdrive/backend/node/test/e2e/common/user-api.ts +++ b/tdrive/backend/node/test/e2e/common/user-api.ts @@ -409,17 +409,21 @@ export default class UserApi { }); } - async endEditingDocument( - editingSessionKey: string + async updateEditingDocument( + editingSessionKey: string, + keepEditing: boolean = false, + userId: string | null = null, ): Promise { const fullPath = `${__dirname}/assets/${UserApi.ALL_FILES[0]}`; const readable= Readable.from(fs.createReadStream(fullPath)); const form = formAutoContent({ file: readable }); form.headers["authorization"] = `Bearer ${this.jwt}`; - + let queryString = keepEditing ? "keepEditing=true" : ""; + if (userId) + queryString += `${queryString.length ? "&" : ""}userId=${encodeURIComponent(userId)}`; return await this.platform.app.inject({ method: "POST", - url: `${UserApi.DOC_URL}/editing_session/${editingSessionKey}`, + url: `${UserApi.DOC_URL}/editing_session/${encodeURIComponent(editingSessionKey)}${queryString ? "?" : ""}${queryString}`, headers: { authorization: `Bearer ${this.jwt}` }, diff --git a/tdrive/backend/node/test/e2e/documents/editing-session.spec.ts b/tdrive/backend/node/test/e2e/documents/editing-session.spec.ts index fae3f747..3f966049 100644 --- a/tdrive/backend/node/test/e2e/documents/editing-session.spec.ts +++ b/tdrive/backend/node/test/e2e/documents/editing-session.spec.ts @@ -4,7 +4,6 @@ import { init, TestPlatform } from "../setup"; import UserApi from "../common/user-api"; import { DriveFile, TYPE as DriveFileType } from "../../../src/services/documents/entities/drive-file"; -import exp = require("node:constants"); import ApplicationsApiService, { ApplicationEditingKeyStatus } from "../../../src/services/applications-api"; import { afterEach } from "node:test"; import Application from "../../../src/services/applications/entities/application"; @@ -135,7 +134,7 @@ describe("the Drive's documents' editing session kind-of-lock", () => { //given const editingSessionKey = await currentUser.beginEditingDocumentExpectOk(temporaryDocument.id, 'e2e_testing'); //when - const response = await currentUser.endEditingDocument(editingSessionKey); + const response = await currentUser.updateEditingDocument(editingSessionKey); //then expect(response.statusCode).toBe(200); diff --git a/tdrive/connectors/onlyoffice-connector/src/services/drive.service.ts b/tdrive/connectors/onlyoffice-connector/src/services/drive.service.ts index c006991b..2199bb66 100644 --- a/tdrive/connectors/onlyoffice-connector/src/services/drive.service.ts +++ b/tdrive/connectors/onlyoffice-connector/src/services/drive.service.ts @@ -93,15 +93,15 @@ class DriveService implements IDriveService { } } - public async addEditingSessionVersion(editing_session_key: string, url: string, user_token?: string) { - return this.updateEditing(editing_session_key, url, true, user_token); + public async addEditingSessionVersion(editing_session_key: string, url: string, userId?: string) { + return this.updateEditing(editing_session_key, url, true, userId); } - public async endEditing(editing_session_key: string, url: string, user_token?: string) { - return this.updateEditing(editing_session_key, url, false, user_token); + public async endEditing(editing_session_key: string, url: string, userId?: string) { + return this.updateEditing(editing_session_key, url, false, userId); } - private async updateEditing(editing_session_key: string, url: string, keepEditing: boolean, user_token?: string) { + private async updateEditing(editing_session_key: string, url: string, keepEditing: boolean, userId?: string) { try { if (!url) { throw Error('no url found'); @@ -121,9 +121,9 @@ class DriveService implements IDriveService { await apiService.post({ url: makeEditingSessionItemUrl(editing_session_key, { keepEditing: keepEditing ? 'true' : null, + userId, }), payload: form, - token: user_token, headers: form.getHeaders(), }); } catch (error) {