diff --git a/src/BasePlatform.ts b/src/BasePlatform.ts index c1a64848d2..05dd437f94 100644 --- a/src/BasePlatform.ts +++ b/src/BasePlatform.ts @@ -477,6 +477,8 @@ export default abstract class BasePlatform { // The redirect URL has to exactly match that registered at the OIDC server, so // ensure that the fragment part of the URL is empty. url.hash = ""; + // Set no_universal_links=true to prevent the callback being handled by Element X installed on macOS Apple Silicon + url.searchParams.set("no_universal_links", "true"); return url; } diff --git a/src/vector/app.tsx b/src/vector/app.tsx index d0c689a2b4..0d440ff963 100644 --- a/src/vector/app.tsx +++ b/src/vector/app.tsx @@ -43,6 +43,7 @@ function onTokenLoginCompleted(): void { // a little nasty but let's redirect to clear them. const url = new URL(window.location.href); + url.searchParams.delete("no_universal_links"); url.searchParams.delete("loginToken"); url.searchParams.delete("state"); url.searchParams.delete("code"); diff --git a/test/unit-tests/vector/init-test.ts b/test/unit-tests/vector/init-test.ts index 7f7d760360..22e3b75ae9 100644 --- a/test/unit-tests/vector/init-test.ts +++ b/test/unit-tests/vector/init-test.ts @@ -1,3 +1,8 @@ +/** + * @jest-environment jsdom + * @jest-environment-options {"url": "https://app.element.io/?loginToken=123&state=abc&code=xyz&no_universal_links&something_else=value"} + */ + /* Copyright 2024 New Vector Ltd. @@ -42,11 +47,27 @@ describe("showError", () => { describe("loadApp", () => { beforeEach(setUpMatrixChatDiv); - it("should set window.matrixChat to the MatrixChat instance", async () => { + beforeEach(async () => { fetchMock.get("https://matrix.org/_matrix/client/versions", { versions: ["v1.6"] }); SdkConfig.put({ default_server_config: { "m.homeserver": { base_url: "https://matrix.org" } } }); + }); + it("should set window.matrixChat to the MatrixChat instance", async () => { await loadApp({}); await waitFor(() => expect(window.matrixChat).toBeInstanceOf(MatrixChat)); }); + + it("should pass onTokenLoginCompleted which strips searchParams to MatrixChat", async () => { + const spy = jest.spyOn(window.history, "replaceState"); + + await loadApp({}); + await waitFor(() => expect(window.matrixChat).toBeInstanceOf(MatrixChat)); + window.matrixChat!.props.onTokenLoginCompleted(); + + expect(spy).toHaveBeenCalledWith( + null, + "", + expect.stringContaining("https://app.element.io/?something_else=value"), + ); + }); });