Fix credentials fixture when used with MAS (#34234)

* Fix credentials fixture when used with MAS

Without this it'd be using a Native OAuth2 session token but Element Web wouldn't know it was OAuth2-native and thus things like logout were broken

* Test by augmenting the dehydration test which previously failed using the `user` fixture

* Discard changes to apps/web/playwright/e2e/crypto/dehydration-mas.spec.ts
This commit is contained in:
Michael Telatynski
2026-07-13 16:31:57 +00:00
committed by GitHub
parent 157c6008d4
commit c6b52b8a73
5 changed files with 15 additions and 18 deletions
@@ -17,8 +17,6 @@ import { type Credentials } from "../utils/api.js";
/** /**
* Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials. * Adds an initScript to the given page which will populate localStorage appropriately so that Element will use the given credentials.
*
* Warning: this is an incomplete implementation, particularly in MAS environments: for example, a logout operation will not work correctly.
*/ */
export async function populateLocalStorageWithCredentials(page: Page, credentials: Credentials) { export async function populateLocalStorageWithCredentials(page: Page, credentials: Credentials) {
await page.addInitScript( await page.addInitScript(
@@ -31,13 +29,9 @@ export async function populateLocalStorageWithCredentials(page: Page, credential
window.localStorage.setItem("mx_has_pickle_key", "false"); window.localStorage.setItem("mx_has_pickle_key", "false");
window.localStorage.setItem("mx_has_access_token", "true"); window.localStorage.setItem("mx_has_access_token", "true");
// XXX: If the homeserver is using MAS, then Element uses additional localstorage settings to store more if (credentials.oauthClientId) {
// data. The fact that we don't populate them means that, for example, when you hit "Remove this device" in window.localStorage.setItem("mx_oidc_client_id", credentials.oauthClientId);
// the app, it attempts to hit the legacy `/logout` endpoint, which returns a 40x error, which is silently }
// ignored.
//
// If you fix this, (1) yay! (2) please remember to update the warning on the doc-comments of this method
// and its callers.
window.localStorage.setItem( window.localStorage.setItem(
"mx_local_settings", "mx_local_settings",
@@ -73,9 +67,6 @@ export interface TestFixtures {
* but adds an initScript which will populate localStorage with the user's details from * but adds an initScript which will populate localStorage with the user's details from
* {@link #credentials} and {@link #homeserver}. * {@link #credentials} and {@link #homeserver}.
* *
* Warning: this is an incomplete implementation, particularly in MAS environments: for example, a logout operation
* will not work correctly.
*
* Similar to {@link #user}, but doesn't load the app. * Similar to {@link #user}, but doesn't load the app.
*/ */
pageWithCredentials: Page; pageWithCredentials: Page;
@@ -84,9 +75,6 @@ export interface TestFixtures {
* A (rather poorly-named) test fixture which registers a user per {@link #credentials}, stores * A (rather poorly-named) test fixture which registers a user per {@link #credentials}, stores
* the credentials into localStorage per {@link #pageWithCredentials}, and then loads the front page of the * the credentials into localStorage per {@link #pageWithCredentials}, and then loads the front page of the
* app. * app.
*
* Warning: the user credentials are an incomplete implementation, particularly in MAS environments: for example, a logout operation
* will not work correctly.
*/ */
user: Credentials; user: Credentials;
} }
@@ -139,6 +139,12 @@ const DEFAULT_CONFIG = {
per_second: 1, per_second: 1,
}, },
}, },
clients: [
{
client_id: "01ARZ3NDEKTSV4RRFFQ69G5FAV",
client_auth_method: "none",
},
],
} satisfies MasConfig; } satisfies MasConfig;
/** /**
@@ -209,6 +215,7 @@ export class MatrixAuthenticationServiceContainer extends GenericContainer {
`http://localhost:${port}`, `http://localhost:${port}`,
this.args, this.args,
this.config.matrix.secret, this.config.matrix.secret,
this.config.clients![0].client_id,
); );
} }
} }
@@ -224,6 +231,7 @@ export class StartedMatrixAuthenticationServiceContainer extends AbstractStarted
public readonly baseUrl: string, public readonly baseUrl: string,
private readonly args: string[], private readonly args: string[],
public readonly sharedSecret: string, public readonly sharedSecret: string,
public readonly staticClientId: string,
) { ) {
super(container); super(container);
} }
@@ -629,7 +629,7 @@ export class StartedSynapseWithMasContainer extends StartedSynapseContainer {
*/ */
public async registerUser(username: string, password: string, displayName?: string): Promise<Credentials> { public async registerUser(username: string, password: string, displayName?: string): Promise<Credentials> {
const registered = await this.mas.registerUser(username, password, displayName); const registered = await this.mas.registerUser(username, password, displayName);
return { ...registered, homeserverBaseUrl: this.baseUrl }; return { ...registered, homeserverBaseUrl: this.baseUrl, oauthClientId: this.mas.staticClientId };
} }
/** /**
@@ -74,6 +74,9 @@ export interface Credentials {
/** The domain part of the user's matrix ID. */ /** The domain part of the user's matrix ID. */
homeServer: string; homeServer: string;
/** The OAuth2 Client ID used by this client for native OAuth2 sessions **/
oauthClientId?: string;
password: string | null; // null for password-less users password: string | null; // null for password-less users
displayName?: string; displayName?: string;
username: string; // the localpart of the userId username: string; // the localpart of the userId
@@ -14,8 +14,6 @@ import { routeConfigJson } from "./config_json.js";
import { populateLocalStorageWithCredentials } from "../fixtures/user.js"; import { populateLocalStorageWithCredentials } from "../fixtures/user.js";
/** Create a new instance of the application, in a separate browser context, using the given credentials. /** Create a new instance of the application, in a separate browser context, using the given credentials.
*
* Warning: `populateLocalStorageWithCredentials` is an incomplete implementation, particularly in MAS environments: for example, a logout operation will not work correctly.
* *
* @param browser - the browser to use * @param browser - the browser to use
* @param credentials - the credentials to use for the new instance * @param credentials - the credentials to use for the new instance