Skip to content
This repository was archived by the owner on Oct 22, 2024. It is now read-only.
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
89 changes: 45 additions & 44 deletions playwright/pages/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { Logger } from "matrix-js-sdk/src/logger";
import type { SecretStorageKeyDescription } from "matrix-js-sdk/src/secret-storage";
import type { Credentials, HomeserverInstance } from "../plugins/homeserver";
import type { GeneratedSecretStorageKey } from "matrix-js-sdk/src/crypto-api";
import { Client } from "./client";
import { bootstrapCrossSigningForClient, Client } from "./client";

export interface CreateBotOpts {
/**
Expand Down Expand Up @@ -90,9 +90,13 @@ export class Bot extends Client {
}

protected async getClientHandle(): Promise<JSHandle<ExtendedMatrixClient>> {
if (this.handlePromise) return this.handlePromise;
if (!this.handlePromise) this.handlePromise = this.buildClient();
return this.handlePromise;
}

this.handlePromise = this.page.evaluateHandle(
private async buildClient(): Promise<JSHandle<ExtendedMatrixClient>> {
const credentials = await this.getCredentials();
const clientHandle = await this.page.evaluateHandle(
async ({ homeserver, credentials, opts }) => {
function getLogger(loggerName: string): Logger {
const logger = {
Expand Down Expand Up @@ -172,53 +176,50 @@ export class Bot extends Client {
});
}

if (!opts.startClient) {
return cli;
}

await cli.initRustCrypto({ useIndexedDB: false });
cli.setGlobalErrorOnUnknownDevices(false);
await cli.startClient();

if (opts.bootstrapCrossSigning) {
// XXX: workaround https://github.com/element-hq/element-web/issues/26755
// wait for out device list to be available, as a proxy for the device keys having been uploaded.
await cli.getCrypto()!.getUserDeviceInfo([credentials.userId]);

await cli.getCrypto()!.bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (func) => {
await func({
type: "m.login.password",
identifier: {
type: "m.id.user",
user: credentials.userId,
},
password: credentials.password,
});
},
});
}

if (opts.bootstrapSecretStorage) {
const passphrase = "new passphrase";
const recoveryKey = await cli.getCrypto().createRecoveryKeyFromPassphrase(passphrase);
Object.assign(cli, { __playwright_recovery_key: recoveryKey });

await cli.getCrypto()!.bootstrapSecretStorage({
setupNewSecretStorage: true,
setupNewKeyBackup: true,
createSecretStorageKey: () => Promise.resolve(recoveryKey),
});
}

return cli;
},
{
homeserver: this.homeserver.config,
credentials: await this.getCredentials(),
credentials,
opts: this.opts,
},
);
return this.handlePromise;

// If we weren't configured to start the client, bail out now.
if (!this.opts.startClient) {
return clientHandle;
}

await clientHandle.evaluate(async (cli) => {
await cli.initRustCrypto({ useIndexedDB: false });
cli.setGlobalErrorOnUnknownDevices(false);
await cli.startClient();
});

if (this.opts.bootstrapCrossSigning) {
// XXX: workaround https://github.com/element-hq/element-web/issues/26755
// wait for out device list to be available, as a proxy for the device keys having been uploaded.
await clientHandle.evaluate(async (cli, credentials) => {
await cli.getCrypto()!.getUserDeviceInfo([credentials.userId]);
}, credentials);

await bootstrapCrossSigningForClient(clientHandle, credentials);
}

if (this.opts.bootstrapSecretStorage) {
await clientHandle.evaluate(async (cli) => {
const passphrase = "new passphrase";
const recoveryKey = await cli.getCrypto().createRecoveryKeyFromPassphrase(passphrase);
Object.assign(cli, { __playwright_recovery_key: recoveryKey });

await cli.getCrypto()!.bootstrapSecretStorage({
setupNewSecretStorage: true,
setupNewKeyBackup: true,
createSecretStorageKey: () => Promise.resolve(recoveryKey),
});
});
}

return clientHandle;
}
}
45 changes: 30 additions & 15 deletions playwright/pages/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,24 +356,11 @@ export class Client {
}

/**
* Boostraps cross-signing.
* Bootstraps cross-signing.
*/
public async bootstrapCrossSigning(credentials: Credentials): Promise<void> {
const client = await this.prepareClient();
return client.evaluate(async (client, credentials) => {
await client.getCrypto().bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (func) => {
await func({
type: "m.login.password",
identifier: {
type: "m.id.user",
user: credentials.userId,
},
password: credentials.password,
});
},
});
}, credentials);
return bootstrapCrossSigningForClient(client, credentials);
}

/**
Expand Down Expand Up @@ -439,3 +426,31 @@ export class Client {
);
}
}

/** Call `CryptoApi.bootstrapCrossSigning` on the given Matrix client, using the given credentials to authenticate
* the UIA request.
*/
export function bootstrapCrossSigningForClient(
client: JSHandle<MatrixClient>,
credentials: Credentials,
resetKeys: boolean = false,
) {
return client.evaluate(
async (client, { credentials, resetKeys }) => {
await client.getCrypto().bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (func) => {
await func({
type: "m.login.password",
identifier: {
type: "m.id.user",
user: credentials.userId,
},
password: credentials.password,
});
},
setupNewCrossSigning: resetKeys,
});
},
{ credentials, resetKeys },
);
}
Loading