diff --git a/tdrive/backend/node/src/services/applications-api/index.ts b/tdrive/backend/node/src/services/applications-api/index.ts index 312566cb..d817e62a 100644 --- a/tdrive/backend/node/src/services/applications-api/index.ts +++ b/tdrive/backend/node/src/services/applications-api/index.ts @@ -14,6 +14,11 @@ export default class ApplicationsApiService extends TdriveService { version = "1"; name = "applicationsapi"; + private static default: ApplicationsApiService; + public static getDefault() { + return this.default; + } + public async doInit(): Promise { const fastify = this.context.getProvider("webserver").getServer(); fastify.register((instance, _opts, next) => { @@ -70,10 +75,23 @@ export default class ApplicationsApiService extends TdriveService { } } } - + ApplicationsApiService.default = this; return this; } + /** Get the configuration of a given `appId` or `undefined` if unknown */ + public getApplicationConfig(appId: string) { + const apps = config.get("applications.plugins") || []; + return apps.find(app => app.id === appId); + } + + /** Get the configuration of a given `appId` or throw an error if unknown */ + public requireApplicationConfig(appId: string) { + const app = this.getApplicationConfig(appId); + if (!app) throw new Error(`Unknown application.id ${JSON.stringify(appId)}`); + return app; + } + /** Send a request to the plugin by its application id * @param url Full URL that doesn't start with a `/` */ @@ -82,9 +100,7 @@ export default class ApplicationsApiService extends TdriveService { url: string, appId: string, ) { - const apps = config.get("applications.plugins") || []; - const app = apps.find(app => app.id === appId); - if (!app) throw new Error(`Unknown application.id ${JSON.stringify(appId)}`); + const app = this.requireApplicationConfig(appId); if (!app.internal_domain) throw new Error(`application.id ${JSON.stringify(appId)} missing an internal_domain`); const signature = jwt.sign( diff --git a/tdrive/backend/node/src/services/documents/services/index.ts b/tdrive/backend/node/src/services/documents/services/index.ts index 5e82cb85..8c70a5eb 100644 --- a/tdrive/backend/node/src/services/documents/services/index.ts +++ b/tdrive/backend/node/src/services/documents/services/index.ts @@ -61,6 +61,7 @@ import config from "config"; import { MultipartFile } from "@fastify/multipart"; import { UploadOptions } from "src/services/files/types"; import { SortType } from "src/core/platform/services/search/api"; +import ApplicationsApiService from "../../applications-api"; export class DocumentsService { version: "1"; @@ -976,9 +977,16 @@ export class DocumentsService { this.logger.error("invalid execution context"); return null; } - - //TODO: This needs to try in a loop depending on oo-connector response - // when there is already a key + if ( + !editorApplicationId || + !ApplicationsApiService.getDefault().getApplicationConfig(editorApplicationId) + ) { + logger.error(`Missing or invalid application ID: ${JSON.stringify(editorApplicationId)}`); + CrudException.throwMe( + new Error("Unknown appId"), + new CrudException("Missing or invalid application ID", 400), + ); + } let newKey: string; try { newKey = EditingSessionKeyFormat.generate( diff --git a/tdrive/backend/node/test/e2e/common/user-api.ts b/tdrive/backend/node/test/e2e/common/user-api.ts index ec047e68..133a3eff 100644 --- a/tdrive/backend/node/test/e2e/common/user-api.ts +++ b/tdrive/backend/node/test/e2e/common/user-api.ts @@ -516,7 +516,7 @@ export default class UserApi { async getDocumentByEditingKey(editing_session_key: string) { return await this.platform.app.inject({ method: "GET", - url: `${UserApi.DOC_URL}/companies/${this.platform.workspace.company_id}/item/editing_session/${encodeURIComponent(editing_session_key)}`, + url: `${UserApi.DOC_URL}/editing_session/${encodeURIComponent(editing_session_key)}`, 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 845ec9c9..fd5d0231 100644 --- a/tdrive/backend/node/test/e2e/documents/editing-session.spec.ts +++ b/tdrive/backend/node/test/e2e/documents/editing-session.spec.ts @@ -1,10 +1,13 @@ -import { describe, beforeAll, beforeEach, it, expect, afterAll } from "@jest/globals"; +import { describe, beforeAll, beforeEach, it, expect, afterAll, jest } from "@jest/globals"; 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 from "../../../src/services/applications-api"; +import { afterEach } from "node:test"; +import Application from "../../../src/services/applications/entities/application"; describe("the Drive's documents' editing session kind-of-lock", () => { let platform: TestPlatform | null; @@ -49,6 +52,11 @@ describe("the Drive's documents' editing session kind-of-lock", () => { parent_id: currentUserRoot, scope: "personal", }); + jest.spyOn(ApplicationsApiService.getDefault(), 'getApplicationConfig').mockImplementation((id) => id === "e2e_testing" ? {} as Application : undefined); + }); + + afterEach(() => { + jest.restoreAllMocks(); }); it("atomicCompareAndSet allows a single value at a time", async () => {