Fix Native OIDC for Element Desktop (#12253)

* Reuse exported common type

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Improve client metadata used for OIDC dynamic registration

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix Native OIDC for Element Desktop by including ssoid in the url_state of the /auth call

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Reuse exported common type

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Improve client metadata used for OIDC dynamic registration

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix typo

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Fix test

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Mock PlatformPeg

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Mock platform

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Add comment

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Improve comment

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update src/BasePlatform.ts

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
Michael Telatynski 2024-02-19 15:10:11 +00:00 committed by GitHub
parent c71b8fdf78
commit 618462ba06
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 23 additions and 5 deletions

View file

@ -313,7 +313,11 @@ export default abstract class BasePlatform {
return null;
}
protected getSSOCallbackUrl(fragmentAfterLogin = ""): URL {
/**
* The URL to return to after a successful SSO/OIDC authentication
* @param fragmentAfterLogin optional fragment for specific view to return to
*/
public getSSOCallbackUrl(fragmentAfterLogin = ""): URL {
const url = new URL(window.location.href);
url.hash = fragmentAfterLogin;
return url;
@ -478,4 +482,12 @@ export default abstract class BasePlatform {
policyUri: config.privacy_policy_url,
};
}
/**
* Suffix to append to the `state` parameter of OIDC /auth calls. Will be round-tripped to the callback URI.
* Currently only required for ElectronPlatform for passing element-desktop-ssoid.
*/
public getOidcClientState(): string {
return "";
}
}

View file

@ -777,7 +777,7 @@ async function createOidcTokenRefresher(credentials: IMatrixClientCreds): Promis
try {
const clientId = getStoredOidcClientId();
const idTokenClaims = getStoredOidcIdTokenClaims();
const redirectUri = window.location.origin;
const redirectUri = PlatformPeg.get()!.getSSOCallbackUrl().href;
const deviceId = credentials.deviceId;
if (!deviceId) {
throw new Error("Expected deviceId in user credentials.");

View file

@ -21,6 +21,7 @@ import { OidcClient } from "oidc-client-ts";
import { getStoredOidcTokenIssuer, getStoredOidcClientId } from "../../utils/oidc/persistOidcSettings";
import { getDelegatedAuthAccountUrl } from "../../utils/oidc/getDelegatedAuthAccountUrl";
import PlatformPeg from "../../PlatformPeg";
/**
* @experimental
@ -139,7 +140,7 @@ export class OidcClientStore {
...metadata,
authority: metadata.issuer,
signingKeys,
redirect_uri: window.location.origin,
redirect_uri: PlatformPeg.get()!.getSSOCallbackUrl().href,
client_id: clientId,
});
} catch (error) {

View file

@ -21,6 +21,7 @@ import { randomString } from "matrix-js-sdk/src/randomstring";
import { IdTokenClaims } from "oidc-client-ts";
import { OidcClientError } from "./error";
import PlatformPeg from "../../PlatformPeg";
/**
* Start OIDC authorization code flow
@ -39,7 +40,7 @@ export const startOidcLogin = async (
identityServerUrl?: string,
isRegistration?: boolean,
): Promise<void> => {
const redirectUri = window.location.origin;
const redirectUri = PlatformPeg.get()!.getSSOCallbackUrl().href;
const nonce = randomString(10);
@ -53,6 +54,7 @@ export const startOidcLogin = async (
identityServerUrl,
nonce,
prompt,
urlState: PlatformPeg.get()?.getOidcClientState(),
});
window.location.href = authorizationUrl;

View file

@ -23,7 +23,7 @@ import { discoverAndValidateAuthenticationConfig } from "matrix-js-sdk/src/oidc/
import { OidcError } from "matrix-js-sdk/src/oidc/error";
import { OidcClientStore } from "../../../src/stores/oidc/OidcClientStore";
import { flushPromises, getMockClientWithEventEmitter } from "../../test-utils";
import { flushPromises, getMockClientWithEventEmitter, mockPlatformPeg } from "../../test-utils";
import { mockOpenIdConfiguration } from "../../test-utils/oidc";
jest.mock("matrix-js-sdk/src/oidc/discovery", () => ({
@ -58,6 +58,7 @@ describe("OidcClientStore", () => {
jest.spyOn(logger, "error").mockClear();
fetchMock.get(`${metadata.issuer}.well-known/openid-configuration`, metadata);
mockPlatformPeg();
});
describe("isUserAuthenticatedWithOidc()", () => {

View file

@ -23,6 +23,7 @@ import { mocked } from "jest-mock";
import { completeOidcLogin, startOidcLogin } from "../../../src/utils/oidc/authorize";
import { makeDelegatedAuthConfig } from "../../test-utils/oidc";
import { OidcClientError } from "../../../src/utils/oidc/error";
import { mockPlatformPeg } from "../../test-utils";
jest.unmock("matrix-js-sdk/src/randomstring");
@ -53,6 +54,7 @@ describe("OIDC authorization", () => {
};
jest.spyOn(randomStringUtils, "randomString").mockRestore();
mockPlatformPeg();
});
beforeAll(() => {