From 24ef7a316ff62830f907d316b48e1e91d5c0cf71 Mon Sep 17 00:00:00 2001 From: Thor Arne Johansen Date: Tue, 28 Nov 2023 17:05:39 +0100 Subject: [PATCH] WIP Extension mechanism --- src/modules/ModuleRunner.ts | 25 +++++- test/modules/MockModule.ts | 39 ++++++++ test/modules/ModuleRunner-test.ts | 18 +++- .../__snapshots__/HTMLExport-test.ts.snap | 88 +++++++++++++++++++ 4 files changed, 167 insertions(+), 3 deletions(-) diff --git a/src/modules/ModuleRunner.ts b/src/modules/ModuleRunner.ts index 1a94eb16b385..2afb2b8178ec 100644 --- a/src/modules/ModuleRunner.ts +++ b/src/modules/ModuleRunner.ts @@ -16,8 +16,7 @@ limitations under the License. import { safeSet } from "matrix-js-sdk/src/utils"; import { TranslationStringsObject } from "@matrix-org/react-sdk-module-api/lib/types/translations"; -import { AnyLifecycle } from "@matrix-org/react-sdk-module-api/lib/lifecycles/types"; - +import { AnyLifecycle, ProxiedExtensions } from "@matrix-org/react-sdk-module-api/lib/lifecycles/types"; import { AppModule } from "./AppModule"; import { ModuleFactory } from "./ModuleFactory"; @@ -85,4 +84,26 @@ export class ModuleRunner { module.module.emit(lifecycleEvent, ...args); } } + + + public extensionMethods = new ProxiedExtensions(this.modules); + + // /** + // * Invokes a method in any of the registeres modules (only a single module can register a fetcher of a given type). + // * @param extensionMethod The extension method to call + // * @param args The arguments for the method. + // */ + // public invokeMethod(extensionMethod: AnyExtensionMethod, ...args: any[]): T | undefined{ + // console.log("Try invokeMethod: ", extensionMethod); + // for (const module of this.modules) { + // let method = module.module.methods.get(extensionMethod); + // if(method){ + // console.log("Found. invoking method: ", extensionMethod); + // var methodResult = method(args); + // return methodResult; + // } + // } + // console.log("Method not found. returning undefined"); + // return undefined; + // } } diff --git a/test/modules/MockModule.ts b/test/modules/MockModule.ts index ab29b025086b..748c4324569b 100644 --- a/test/modules/MockModule.ts +++ b/test/modules/MockModule.ts @@ -18,6 +18,8 @@ import { RuntimeModule } from "@matrix-org/react-sdk-module-api/lib/RuntimeModul import { ModuleApi } from "@matrix-org/react-sdk-module-api/lib/ModuleApi"; import { ModuleRunner } from "../../src/modules/ModuleRunner"; +import { AllExtensions } from "@matrix-org/react-sdk-module-api/lib/lifecycles/types"; +import { CryptoSetupExtensionsBase, IExtendedMatrixClientCreds } from "@matrix-org/react-sdk-module-api/lib/lifecycles/SecurityLifecycle"; export class MockModule extends RuntimeModule { public get apiInstance(): ModuleApi { @@ -28,6 +30,27 @@ export class MockModule extends RuntimeModule { super(moduleApi); } } +export class MockModuleWithCryptoSetupExtension extends RuntimeModule { + public get apiInstance(): ModuleApi { + return this.moduleApi; + } + + extensions?: AllExtensions | undefined = { + cryptoSetup: new (class extends CryptoSetupExtensionsBase { + GetSecretStorageKey() { + return "my secret storage key" + } + + ExamineLoginResponse(response: any, credentials: IExtendedMatrixClientCreds): void { + credentials.secureBackupKey = "my secure backup key"; + } + })() + } + + public constructor(moduleApi: ModuleApi) { + super(moduleApi); + } +} export function registerMockModule(): MockModule { let module: MockModule | undefined; @@ -43,3 +66,19 @@ export function registerMockModule(): MockModule { } return module; } + +export function registerMockModuleWithCryptoSetupExtension(): MockModuleWithCryptoSetupExtension { + let module: MockModuleWithCryptoSetupExtension | undefined; + + ModuleRunner.instance.registerModule((api) => { + if (module) { + throw new Error("State machine error: ModuleRunner created the module twice"); + } + module = new MockModuleWithCryptoSetupExtension(api); + return module; + }); + if (!module) { + throw new Error("State machine error: ModuleRunner did not create module"); + } + return module; +} diff --git a/test/modules/ModuleRunner-test.ts b/test/modules/ModuleRunner-test.ts index 175c62c9e6b3..d28e7d90fabb 100644 --- a/test/modules/ModuleRunner-test.ts +++ b/test/modules/ModuleRunner-test.ts @@ -16,7 +16,12 @@ limitations under the License. import { RoomPreviewOpts, RoomViewLifecycle } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle"; -import { MockModule, registerMockModule } from "./MockModule"; +import { + MockModule, + registerMockModule, + registerMockModuleWithCryptoSetupExtension +} from "./MockModule"; + import { ModuleRunner } from "../../src/modules/ModuleRunner"; describe("ModuleRunner", () => { @@ -49,4 +54,15 @@ describe("ModuleRunner", () => { ]); }); }); + + describe("extensionMethods", () => { + + it("should return value when extension provided by a registered module", async () => { + const module1 = registerMockModule(); + const module2 = registerMockModuleWithCryptoSetupExtension(); + + var result = ModuleRunner.instance.extensionMethods.extensions.cryptoSetup?.GetSecretStorageKey(); + expect(results).toEqual("") + }); + }); }); diff --git a/test/utils/exportUtils/__snapshots__/HTMLExport-test.ts.snap b/test/utils/exportUtils/__snapshots__/HTMLExport-test.ts.snap index 9e0fd1a8824e..a89e7e775ab1 100644 --- a/test/utils/exportUtils/__snapshots__/HTMLExport-test.ts.snap +++ b/test/utils/exportUtils/__snapshots__/HTMLExport-test.ts.snap @@ -91,3 +91,91 @@ exports[`HTMLExport should export 1`] = ` exports[`HTMLExport should have an SDK-branded destination file name 1`] = `"Element - My Test Room Welcome - Chat Export - 2022-11-17T16-58-32.517Z.zip"`; exports[`HTMLExport should have an SDK-branded destination file name 2`] = `"BrandedChatWithSlashesForFun - My Test Room Welcome - Chat Export - 2022-11-17T16-58-32.517Z.zip"`; + +exports[`HTMLExport should include the creation event 1`] = ` +" + + + + + + + + + Exported Data + + +
+
+
+
+
+
+
+
+ ! +
+
+
+
+ !myroom:example.org +
+
+
+
+
+ +
+
+
+
+
+
    +
    + ! +

    !myroom:example.org

    +

    created this room.

    This is the start of export of !myroom:example.org. Exported by @userId:matrix.org at 11/17/2022.

    +
    +

    +
    +
  1. @user49:example.com
    Message #49
  2. @user48:example.com
    Message #48
  3. @user47:example.com
    Message #47
  4. @user46:example.com
    Message #46
  5. @user45:example.com
    Message #45
  6. @user44:example.com
    Message #44
  7. @user43:example.com
    Message #43
  8. @user42:example.com
    Message #42
  9. @user41:example.com
    Message #41
  10. @user40:example.com
    Message #40
  11. @user39:example.com
    Message #39
  12. @user38:example.com
    Message #38
  13. @user37:example.com
    Message #37
  14. @user36:example.com
    Message #36
  15. @user35:example.com
    Message #35
  16. @user34:example.com
    Message #34
  17. @user33:example.com
    Message #33
  18. @user32:example.com
    Message #32
  19. @user31:example.com
    Message #31
  20. @user30:example.com
    Message #30
  21. @user29:example.com
    Message #29
  22. @user28:example.com
    Message #28
  23. @user27:example.com
    Message #27
  24. @user26:example.com
    Message #26
  25. @user25:example.com
    Message #25
  26. @user24:example.com
    Message #24
  27. @user23:example.com
    Message #23
  28. @user22:example.com
    Message #22
  29. @user21:example.com
    Message #21
  30. @user20:example.com
    Message #20
  31. @user19:example.com
    Message #19
  32. @user18:example.com
    Message #18
  33. @user17:example.com
    Message #17
  34. @user16:example.com
    Message #16
  35. @user15:example.com
    Message #15
  36. @user14:example.com
    Message #14
  37. @user13:example.com
    Message #13
  38. @user12:example.com
    Message #12
  39. @user11:example.com
    Message #11
  40. @user10:example.com
    Message #10
  41. @user9:example.com
    Message #9
  42. @user8:example.com
    Message #8
  43. @user7:example.com
    Message #7
  44. @user6:example.com
    Message #6
  45. @user5:example.com
    Message #5
  46. @user4:example.com
    Message #4
  47. @user3:example.com
    Message #3
  48. @user2:example.com
    Message #2
  49. @user1:example.com
    Message #1
  50. @user0:example.com
    Message #0
  51. +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+ + " +`;