Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Fixes user authentication when registering via the module API #10257

Merged
merged 7 commits into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions src/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ export async function hydrateSession(credentials: IMatrixClientCreds): Promise<M
}

/**
* fires on_logging_in, optionally clears localstorage, persists new credentials
* optionally clears localstorage, persists new credentials
* to localstorage, starts the new client.
*
* @param {IMatrixClientCreds} credentials
Expand All @@ -595,15 +595,6 @@ async function doSetLoggedIn(credentials: IMatrixClientCreds, clearStorageEnable
" freshLogin: " + credentials.freshLogin,
);

// This is dispatched to indicate that the user is still in the process of logging in
// because async code may take some time to resolve, breaking the assumption that
// `setLoggedIn` takes an "instant" to complete, and dispatch `on_logged_in` a few ms
// later than MatrixChat might assume.
//
// we fire it *synchronously* to make sure it fires before on_logged_in.
// (dis.dispatch uses `window.setTimeout`, which does not guarantee ordering.)
dis.dispatch({ action: "on_logging_in" }, true);

if (clearStorageEnabled) {
await clearStorage();
}
Expand Down
18 changes: 18 additions & 0 deletions src/modules/ProxiedModuleApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { MatrixClientPeg } from "../MatrixClientPeg";
import { getCachedRoomIDForAlias } from "../RoomAliasCache";
import { Action } from "../dispatcher/actions";
import { OverwriteLoginPayload } from "../dispatcher/payloads/OverwriteLoginPayload";
import { ActionPayload } from "../dispatcher/payloads";

/**
* Glue between the `ModuleApi` interface and the react-sdk. Anticipates one instance
Expand All @@ -44,6 +45,18 @@ import { OverwriteLoginPayload } from "../dispatcher/payloads/OverwriteLoginPayl
export class ProxiedModuleApi implements ModuleApi {
private cachedTranslations: Optional<TranslationStringsObject>;

private overrideLoginResolve?: () => void;

public constructor() {
dispatcher.register(this.onAction);
}

private onAction = (payload: ActionPayload): void => {
if (payload.action === Action.OnLoggedIn) {
this.overrideLoginResolve?.();
}
};

/**
* All custom translations used by the associated module.
*/
Expand Down Expand Up @@ -155,6 +168,11 @@ export class ProxiedModuleApi implements ModuleApi {
},
true,
); // require to be sync to match inherited interface behaviour

// wait for login to complete
await new Promise<void>((resolve) => {
this.overrideLoginResolve = resolve;
});
}

/**
Expand Down
26 changes: 26 additions & 0 deletions test/modules/ProxiedModuleApi-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ limitations under the License.
*/

import { TranslationStringsObject } from "@matrix-org/react-sdk-module-api/lib/types/translations";
import { AccountAuthInfo } from "@matrix-org/react-sdk-module-api/lib/types/AccountAuthInfo";

import { ProxiedModuleApi } from "../../src/modules/ProxiedModuleApi";
import { stubClient } from "../test-utils";
import { setLanguage } from "../../src/languageHandler";
import { ModuleRunner } from "../../src/modules/ModuleRunner";
import { registerMockModule } from "./MockModule";
import defaultDispatcher from "../../src/dispatcher/dispatcher";
import { Action } from "../../src/dispatcher/actions";

describe("ProxiedApiModule", () => {
afterEach(() => {
Expand All @@ -44,6 +47,29 @@ describe("ProxiedApiModule", () => {
expect(api.translations).toBe(translations);
});

it("should overwriteAccountAuth", async () => {
const dispatchSpy = jest.spyOn(defaultDispatcher, "dispatch");

const api = new ProxiedModuleApi();
const accountInfo = {} as unknown as AccountAuthInfo;
const promise = api.overwriteAccountAuth(accountInfo);

expect(dispatchSpy).toHaveBeenCalledWith(
expect.objectContaining({
action: Action.OverwriteLogin,
credentials: {
...accountInfo,
guest: false,
},
}),
expect.anything(),
);

defaultDispatcher.fire(Action.OnLoggedIn);

await expect(promise).resolves.toBeUndefined();
});

describe("integration", () => {
it("should translate strings using translation system", async () => {
// Test setup
Expand Down