You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-23 17:02:25 +03:00
Add disableKeyStorage() to crypto API (#4742)
* Add disableKeyStorage() to crypto API As an all-in-one method for deleting all server side key storage on the user's account (as the doc hopefully explains). * Add test * const * Can't be disabled here
This commit is contained in:
@@ -2318,6 +2318,43 @@ describe("RustCrypto", () => {
|
|||||||
expect(dehydratedDeviceIsDeleted).toBeTruthy();
|
expect(dehydratedDeviceIsDeleted).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("disableKeyStorage", () => {
|
||||||
|
it("should disable key storage", async () => {
|
||||||
|
const secretStorage = {
|
||||||
|
getDefaultKeyId: jest.fn().mockResolvedValue("bloop"),
|
||||||
|
setDefaultKeyId: jest.fn(),
|
||||||
|
store: jest.fn(),
|
||||||
|
} as unknown as ServerSideSecretStorage;
|
||||||
|
|
||||||
|
fetchMock.get("path:/_matrix/client/v3/room_keys/version", testData.SIGNED_BACKUP_DATA);
|
||||||
|
|
||||||
|
let backupIsDeleted = false;
|
||||||
|
fetchMock.delete("path:/_matrix/client/v3/room_keys/version/1", () => {
|
||||||
|
backupIsDeleted = true;
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
|
let dehydratedDeviceIsDeleted = false;
|
||||||
|
fetchMock.delete("path:/_matrix/client/unstable/org.matrix.msc3814.v1/dehydrated_device", () => {
|
||||||
|
dehydratedDeviceIsDeleted = true;
|
||||||
|
return { device_id: "ADEVICEID" };
|
||||||
|
});
|
||||||
|
|
||||||
|
const rustCrypto = await makeTestRustCrypto(makeMatrixHttpApi(), undefined, undefined, secretStorage);
|
||||||
|
await rustCrypto.disableKeyStorage();
|
||||||
|
|
||||||
|
expect(secretStorage.store).toHaveBeenCalledWith("m.cross_signing.master", null);
|
||||||
|
expect(secretStorage.store).toHaveBeenCalledWith("m.cross_signing.self_signing", null);
|
||||||
|
expect(secretStorage.store).toHaveBeenCalledWith("m.cross_signing.user_signing", null);
|
||||||
|
expect(secretStorage.store).toHaveBeenCalledWith("m.megolm_backup.v1", null);
|
||||||
|
expect(secretStorage.store).toHaveBeenCalledWith("m.secret_storage.key.bloop", null);
|
||||||
|
expect(secretStorage.setDefaultKeyId).toHaveBeenCalledWith(null);
|
||||||
|
|
||||||
|
expect(backupIsDeleted).toBeTruthy();
|
||||||
|
expect(dehydratedDeviceIsDeleted).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Build a MatrixHttpApi instance */
|
/** Build a MatrixHttpApi instance */
|
||||||
|
|||||||
@@ -629,6 +629,16 @@ export interface CryptoApi {
|
|||||||
*/
|
*/
|
||||||
resetKeyBackup(): Promise<void>;
|
resetKeyBackup(): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables server-side key storage and deletes server-side backups.
|
||||||
|
* * Deletes the current key backup version, if any (but not any previous versions).
|
||||||
|
* * Disables 4S, deleting the info for the default key, the default key pointer itself and any
|
||||||
|
* known 4S data (cross-signing keys and the megolm key backup key).
|
||||||
|
* * Deletes any dehydrated devices.
|
||||||
|
* * Sets the "m.org.matrix.custom.backup_disabled" account data flag to indicate that the user has disabled backups.
|
||||||
|
*/
|
||||||
|
disableKeyStorage(): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the given key backup.
|
* Deletes the given key backup.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1276,6 +1276,24 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
|
|||||||
this.checkKeyBackupAndEnable();
|
this.checkKeyBackupAndEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link CryptoApi#disableKeyStorage}.
|
||||||
|
*/
|
||||||
|
public async disableKeyStorage(): Promise<void> {
|
||||||
|
// Get the key backup version we're using
|
||||||
|
const info = await this.getKeyBackupInfo();
|
||||||
|
if (info?.version) {
|
||||||
|
await this.deleteKeyBackupVersion(info.version);
|
||||||
|
} else {
|
||||||
|
logger.error("Can't delete key backup version: no version available");
|
||||||
|
}
|
||||||
|
|
||||||
|
// also turn off 4S, since this is also storing keys on the server.
|
||||||
|
await this.deleteSecretStorage();
|
||||||
|
|
||||||
|
await this.dehydratedDeviceManager.delete();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signs the given object with the current device and current identity (if available).
|
* Signs the given object with the current device and current identity (if available).
|
||||||
* As defined in {@link https://spec.matrix.org/v1.8/appendices/#signing-json | Signing JSON}.
|
* As defined in {@link https://spec.matrix.org/v1.8/appendices/#signing-json | Signing JSON}.
|
||||||
@@ -1447,17 +1465,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
|
|||||||
// Disable backup, and delete all the backups from the server
|
// Disable backup, and delete all the backups from the server
|
||||||
await this.backupManager.deleteAllKeyBackupVersions();
|
await this.backupManager.deleteAllKeyBackupVersions();
|
||||||
|
|
||||||
// Remove the stored secrets in the secret storage
|
this.deleteSecretStorage();
|
||||||
await this.secretStorage.store("m.cross_signing.master", null);
|
|
||||||
await this.secretStorage.store("m.cross_signing.self_signing", null);
|
|
||||||
await this.secretStorage.store("m.cross_signing.user_signing", null);
|
|
||||||
await this.secretStorage.store("m.megolm_backup.v1", null);
|
|
||||||
|
|
||||||
// Remove the recovery key
|
|
||||||
const defaultKeyId = await this.secretStorage.getDefaultKeyId();
|
|
||||||
if (defaultKeyId) await this.secretStorage.store(`m.secret_storage.key.${defaultKeyId}`, null);
|
|
||||||
// Disable the recovery key and the secret storage
|
|
||||||
await this.secretStorage.setDefaultKeyId(null);
|
|
||||||
|
|
||||||
// Reset the cross-signing keys
|
// Reset the cross-signing keys
|
||||||
await this.crossSigningIdentity.bootstrapCrossSigning({
|
await this.crossSigningIdentity.bootstrapCrossSigning({
|
||||||
@@ -1471,6 +1479,24 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, CryptoEventH
|
|||||||
this.logger.debug("resetEncryption: ended");
|
this.logger.debug("resetEncryption: ended");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the secret storage key, default key pointer and all (known) secret storage data
|
||||||
|
* from the user's account data
|
||||||
|
*/
|
||||||
|
private async deleteSecretStorage(): Promise<void> {
|
||||||
|
// Remove the stored secrets in the secret storage
|
||||||
|
await this.secretStorage.store("m.cross_signing.master", null);
|
||||||
|
await this.secretStorage.store("m.cross_signing.self_signing", null);
|
||||||
|
await this.secretStorage.store("m.cross_signing.user_signing", null);
|
||||||
|
await this.secretStorage.store("m.megolm_backup.v1", null);
|
||||||
|
|
||||||
|
// Remove the recovery key
|
||||||
|
const defaultKeyId = await this.secretStorage.getDefaultKeyId();
|
||||||
|
if (defaultKeyId) await this.secretStorage.store(`m.secret_storage.key.${defaultKeyId}`, null);
|
||||||
|
// Disable the recovery key and the secret storage
|
||||||
|
await this.secretStorage.setDefaultKeyId(null);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// SyncCryptoCallbacks implementation
|
// SyncCryptoCallbacks implementation
|
||||||
|
|||||||
Reference in New Issue
Block a user