Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "AsJson" forms of the key import/export methods #4057

Merged
merged 2 commits into from
Feb 8, 2024
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
4 changes: 2 additions & 2 deletions spec/integ/crypto/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1379,7 +1379,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
});
expect(decryptedEvent.getContent().body).toEqual("42");

const exported = await aliceClient.exportRoomKeys();
const exported = await aliceClient.getCrypto()!.exportRoomKeysAsJson();

// start a new client
await aliceClient.stopClient();
Expand All @@ -1395,7 +1395,7 @@ describe.each(Object.entries(CRYPTO_BACKENDS))("crypto (%s)", (backend: string,
keyReceiver = new E2EKeyReceiver(homeserverUrl);
syncResponder = new SyncResponder(homeserverUrl);
await initCrypto(aliceClient);
await aliceClient.importRoomKeys(exported);
await aliceClient.getCrypto()!.importRoomKeysAsJson(exported);
expectAliceKeyQuery({ device_keys: { "@alice:localhost": {} }, failures: {} });
await startClientAndAwaitFirstSync();

Expand Down
25 changes: 24 additions & 1 deletion spec/unit/rust-crypto/rust-crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ describe("RustCrypto", () => {
);
});

describe(".importRoomKeys and .exportRoomKeys", () => {
describe("importing and exporting room keys", () => {
let rustCrypto: RustCrypto;

beforeEach(
Expand Down Expand Up @@ -416,6 +416,29 @@ describe("RustCrypto", () => {

expect(aSession).toStrictEqual(exportedKey);
});

it("should import and export keys as JSON", async () => {
const someRoomKeys = testData.MEGOLM_SESSION_DATA_ARRAY;
let importTotal = 0;
const opt: ImportRoomKeysOpts = {
progressCallback: (stage) => {
importTotal = stage.total ?? 0;
},
};
await rustCrypto.importRoomKeysAsJson(JSON.stringify(someRoomKeys), opt);

expect(importTotal).toBe(someRoomKeys.length);

const keys: Array<IMegolmSessionData> = JSON.parse(await rustCrypto.exportRoomKeysAsJson());
expect(Array.isArray(keys)).toBeTruthy();
expect(keys.length).toBe(someRoomKeys.length);

const aSession = someRoomKeys[0];

const exportedKey = keys.find((k) => k.session_id == aSession.session_id);

expect(aSession).toStrictEqual(exportedKey);
});
});

describe("call preprocess methods", () => {
Expand Down
28 changes: 26 additions & 2 deletions src/crypto-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ export interface CryptoApi {
*/
exportRoomKeys(): Promise<IMegolmSessionData[]>;

/**
* Get a JSON list containing all of the room keys
*
* This should be encrypted before returning it to the user.
*
* @returns a promise which resolves to a JSON string
* encoding a list of session export objects,
* each of which is an IMegolmSessionData
*/
exportRoomKeysAsJson(): Promise<string>;

/**
* Import a list of room keys previously exported by exportRoomKeys
*
Expand All @@ -105,6 +116,17 @@ export interface CryptoApi {
*/
importRoomKeys(keys: IMegolmSessionData[], opts?: ImportRoomKeysOpts): Promise<void>;

/**
* Import a JSON string encoding a list of room keys previously
* exported by exportRoomKeysAsJson
*
* @param keys - a JSON string encoding a list of session export
* objects, each of which is an IMegolmSessionData
* @param opts - options object
* @returns a promise which resolves once the keys have been imported
*/
importRoomKeysAsJson(keys: string, opts?: ImportRoomKeysOpts): Promise<void>;

/**
* Check if the given user has published cross-signing keys.
*
Expand Down Expand Up @@ -593,7 +615,8 @@ export class DeviceVerificationStatus {

/**
* Room key import progress report.
* Used when calling {@link CryptoApi#importRoomKeys} as the parameter of
* Used when calling {@link CryptoApi#importRoomKeys} or
* {@link CryptoApi#importRoomKeysAsJson} as the parameter of
* the progressCallback. Used to display feedback.
*/
export interface ImportRoomKeyProgressData {
Expand All @@ -604,7 +627,8 @@ export interface ImportRoomKeyProgressData {
}

/**
* Options object for {@link CryptoApi#importRoomKeys}.
* Options object for {@link CryptoApi#importRoomKeys} and
* {@link CryptoApi#importRoomKeysAsJson}.
*/
export interface ImportRoomKeysOpts {
/** Reports ongoing progress of the import process. Can be used for feedback. */
Expand Down
23 changes: 23 additions & 0 deletions src/crypto/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3142,6 +3142,16 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
return exportedSessions;
}

/**
* Get a JSON list containing all of the room keys
*
* @returns a JSON string encoding a list of session
* export objects, each of which is an IMegolmSessionData
*/
public async exportRoomKeysAsJson(): Promise<string> {
return JSON.stringify(await this.exportRoomKeys());
}

/**
* Import a list of room keys previously exported by exportRoomKeys
*
Expand Down Expand Up @@ -3184,6 +3194,19 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
).then();
}

/**
* Import a JSON string encoding a list of room keys previously
* exported by exportRoomKeysAsJson
*
* @param keys - a JSON string encoding a list of session export
* objects, each of which is an IMegolmSessionData
* @param opts - options object
* @returns a promise which resolves once the keys have been imported
*/
public async importRoomKeysAsJson(keys: string, opts?: ImportRoomKeysOpts): Promise<void> {
return await this.importRoomKeys(JSON.parse(keys));
}

/**
* Counts the number of end to end session keys that are waiting to be backed up
* @returns Promise which resolves to the number of sessions requiring backup
Expand Down
13 changes: 12 additions & 1 deletion src/rust-crypto/backup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,18 @@ export class RustBackupManager extends TypedEventEmitter<RustBackupCryptoEvents,
* @returns a promise which resolves once the keys have been imported
*/
public async importRoomKeys(keys: IMegolmSessionData[], opts?: ImportRoomKeysOpts): Promise<void> {
const jsonKeys = JSON.stringify(keys);
await this.importRoomKeysAsJson(JSON.stringify(keys), opts);
}

/**
* Import a list of room keys previously exported by exportRoomKeysAsJson
*
* @param keys - a JSON string encoding a list of session export objects,
* each of which is an IMegolmSessionData
* @param opts - options object
* @returns a promise which resolves once the keys have been imported
*/
public async importRoomKeysAsJson(jsonKeys: string, opts?: ImportRoomKeysOpts): Promise<void> {
await this.olmMachine.importExportedRoomKeys(jsonKeys, (progress: BigInt, total: BigInt): void => {
const importOpt: ImportRoomKeyProgressData = {
total: Number(total),
Expand Down
8 changes: 8 additions & 0 deletions src/rust-crypto/rust-crypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,18 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
return JSON.parse(raw);
}

public async exportRoomKeysAsJson(): Promise<string> {
return await this.olmMachine.exportRoomKeys(() => true);
}

public async importRoomKeys(keys: IMegolmSessionData[], opts?: ImportRoomKeysOpts): Promise<void> {
return await this.backupManager.importRoomKeys(keys, opts);
}

public async importRoomKeysAsJson(keys: string, opts?: ImportRoomKeysOpts): Promise<void> {
return await this.backupManager.importRoomKeysAsJson(keys, opts);
}

/**
* Implementation of {@link CryptoApi.userHasCrossSigningKeys}.
*/
Expand Down
Loading