mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-14 01:01:31 +01:00
Tweak device trust crypto service implementation to match mobile late… (#5744)
* Tweak device trust crypto service implementation to match mobile latest which results in more single responsibility methods * Update tests to match device trust crypto service implementation changes
This commit is contained in:
parent
87468a2aa6
commit
e50e524920
@ -69,23 +69,24 @@ export class DeviceTrustCryptoService implements DeviceTrustCryptoServiceAbstrac
|
||||
|
||||
// Send encrypted keys to server
|
||||
const deviceIdentifier = await this.appIdService.getAppId();
|
||||
return this.devicesApiService.updateTrustedDeviceKeys(
|
||||
const deviceResponse = await this.devicesApiService.updateTrustedDeviceKeys(
|
||||
deviceIdentifier,
|
||||
devicePublicKeyEncryptedUserKey.encryptedString,
|
||||
userKeyEncryptedDevicePublicKey.encryptedString,
|
||||
deviceKeyEncryptedDevicePrivateKey.encryptedString
|
||||
);
|
||||
|
||||
// store device key in local/secure storage if enc keys posted to server successfully
|
||||
await this.setDeviceKey(deviceKey);
|
||||
return deviceResponse;
|
||||
}
|
||||
|
||||
async getDeviceKey(): Promise<DeviceKey> {
|
||||
// Check if device key is already stored
|
||||
const existingDeviceKey = await this.stateService.getDeviceKey();
|
||||
return await this.stateService.getDeviceKey();
|
||||
}
|
||||
|
||||
if (existingDeviceKey != null) {
|
||||
return existingDeviceKey;
|
||||
} else {
|
||||
return this.makeDeviceKey();
|
||||
}
|
||||
private async setDeviceKey(deviceKey: DeviceKey): Promise<void> {
|
||||
await this.stateService.setDeviceKey(deviceKey);
|
||||
}
|
||||
|
||||
private async makeDeviceKey(): Promise<DeviceKey> {
|
||||
@ -93,9 +94,6 @@ export class DeviceTrustCryptoService implements DeviceTrustCryptoServiceAbstrac
|
||||
const randomBytes: CsprngArray = await this.cryptoFunctionService.randomBytes(64);
|
||||
const deviceKey = new SymmetricCryptoKey(randomBytes) as DeviceKey;
|
||||
|
||||
// Save device key in secure storage
|
||||
await this.stateService.setDeviceKey(deviceKey);
|
||||
|
||||
return deviceKey;
|
||||
}
|
||||
|
||||
@ -106,7 +104,7 @@ export class DeviceTrustCryptoService implements DeviceTrustCryptoServiceAbstrac
|
||||
encryptedUserKey: any
|
||||
): Promise<UserKey> {
|
||||
// get device key
|
||||
const existingDeviceKey = await this.stateService.getDeviceKey();
|
||||
const existingDeviceKey = await this.getDeviceKey();
|
||||
|
||||
if (!existingDeviceKey) {
|
||||
// TODO: not sure what to do here
|
||||
|
@ -87,44 +87,33 @@ describe("deviceTrustCryptoService", () => {
|
||||
const userKeyBytesLength = 64;
|
||||
|
||||
describe("getDeviceKey", () => {
|
||||
let mockRandomBytes: CsprngArray;
|
||||
let mockDeviceKey: SymmetricCryptoKey;
|
||||
let existingDeviceKey: DeviceKey;
|
||||
let stateSvcGetDeviceKeySpy: jest.SpyInstance;
|
||||
let makeDeviceKeySpy: jest.SpyInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
mockRandomBytes = new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray;
|
||||
mockDeviceKey = new SymmetricCryptoKey(mockRandomBytes);
|
||||
existingDeviceKey = new SymmetricCryptoKey(
|
||||
new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray
|
||||
) as DeviceKey;
|
||||
|
||||
stateSvcGetDeviceKeySpy = jest.spyOn(stateService, "getDeviceKey");
|
||||
makeDeviceKeySpy = jest.spyOn(deviceTrustCryptoService as any, "makeDeviceKey");
|
||||
});
|
||||
|
||||
it("gets a device key when there is not an existing device key", async () => {
|
||||
it("returns null when there is not an existing device key", async () => {
|
||||
stateSvcGetDeviceKeySpy.mockResolvedValue(null);
|
||||
makeDeviceKeySpy.mockResolvedValue(mockDeviceKey);
|
||||
|
||||
const deviceKey = await deviceTrustCryptoService.getDeviceKey();
|
||||
|
||||
expect(stateSvcGetDeviceKeySpy).toHaveBeenCalledTimes(1);
|
||||
expect(makeDeviceKeySpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect(deviceKey).not.toBeNull();
|
||||
expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey);
|
||||
expect(deviceKey).toEqual(mockDeviceKey);
|
||||
expect(deviceKey).toBeNull();
|
||||
});
|
||||
|
||||
it("returns the existing device key without creating a new one when there is an existing device key", async () => {
|
||||
it("returns the device key when there is an existing device key", async () => {
|
||||
stateSvcGetDeviceKeySpy.mockResolvedValue(existingDeviceKey);
|
||||
|
||||
const deviceKey = await deviceTrustCryptoService.getDeviceKey();
|
||||
|
||||
expect(stateSvcGetDeviceKeySpy).toHaveBeenCalledTimes(1);
|
||||
expect(makeDeviceKeySpy).not.toHaveBeenCalled();
|
||||
|
||||
expect(deviceKey).not.toBeNull();
|
||||
expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey);
|
||||
@ -132,6 +121,23 @@ describe("deviceTrustCryptoService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("setDeviceKey", () => {
|
||||
it("sets the device key in the state service", async () => {
|
||||
const stateSvcSetDeviceKeySpy = jest.spyOn(stateService, "setDeviceKey");
|
||||
|
||||
const deviceKey = new SymmetricCryptoKey(
|
||||
new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray
|
||||
) as DeviceKey;
|
||||
|
||||
// TypeScript will allow calling private methods if the object is of type 'any'
|
||||
// This is a hacky workaround, but it allows for cleaner tests
|
||||
await (deviceTrustCryptoService as any).setDeviceKey(deviceKey);
|
||||
|
||||
expect(stateSvcSetDeviceKeySpy).toHaveBeenCalledTimes(1);
|
||||
expect(stateSvcSetDeviceKeySpy).toHaveBeenCalledWith(deviceKey);
|
||||
});
|
||||
});
|
||||
|
||||
describe("makeDeviceKey", () => {
|
||||
it("creates a new non-null 64 byte device key, securely stores it, and returns it", async () => {
|
||||
const mockRandomBytes = new Uint8Array(deviceKeyBytesLength).buffer as CsprngArray;
|
||||
@ -140,8 +146,6 @@ describe("deviceTrustCryptoService", () => {
|
||||
.spyOn(cryptoFunctionService, "randomBytes")
|
||||
.mockResolvedValue(mockRandomBytes);
|
||||
|
||||
const stateSvcSetDeviceKeySpy = jest.spyOn(stateService, "setDeviceKey");
|
||||
|
||||
// TypeScript will allow calling private methods if the object is of type 'any'
|
||||
// This is a hacky workaround, but it allows for cleaner tests
|
||||
const deviceKey = await (deviceTrustCryptoService as any).makeDeviceKey();
|
||||
@ -151,9 +155,6 @@ describe("deviceTrustCryptoService", () => {
|
||||
|
||||
expect(deviceKey).not.toBeNull();
|
||||
expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey);
|
||||
|
||||
expect(stateSvcSetDeviceKeySpy).toHaveBeenCalledTimes(1);
|
||||
expect(stateSvcSetDeviceKeySpy).toHaveBeenCalledWith(deviceKey);
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user