Skip to content

Commit 004efe2

Browse files
Add isBackupDevice to DeviceSharedSecret (#416)
* feat: add isBackupDevice to DeviceSharedSecret and DeviceOnboardingInfo * feat: add showBackupDeviceOnboarding to UIBridge * test: check profile name of backup device * fix: parameters for matchers * fix: typo * refactor: remove showBackupDeviceOnboarding * test: extend error message
1 parent b0cf129 commit 004efe2

File tree

6 files changed

+34
-9
lines changed

6 files changed

+34
-9
lines changed

packages/app-runtime/test/lib/MockUIBridge.matchers.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import { DeviceOnboardingInfoDTO } from "@nmshd/runtime";
12
import { MockUIBridge } from "./MockUIBridge";
23

34
expect.extend({
4-
showDeviceOnboardingCalled(mockUIBridge: unknown, deviceId: string) {
5+
showDeviceOnboardingCalled(mockUIBridge: unknown, predicate: (deviceOnboardingInfo: DeviceOnboardingInfoDTO) => boolean) {
56
if (!(mockUIBridge instanceof MockUIBridge)) {
67
throw new Error("This method can only be used with expect(MockUIBridge).");
78
}
@@ -11,12 +12,12 @@ expect.extend({
1112
return { pass: false, message: () => "The method showDeviceOnboarding was not called." };
1213
}
1314

14-
const matchingCalls = calls.filter((x) => x.deviceOnboardingInfo.id === deviceId);
15+
const matchingCalls = calls.filter((x) => predicate(x.deviceOnboardingInfo));
1516
if (matchingCalls.length === 0) {
1617
return {
1718
pass: false,
1819
message: () =>
19-
`The method showDeviceOnboarding was called, but not with the specified device id '${deviceId}', instead with ids '${calls.map((e) => e.deviceOnboardingInfo.id).join(", ")}'.`
20+
`The method showDeviceOnboarding was called, but not with the specified predicate, instead with payloads '${calls.map((e) => JSON.stringify(e.deviceOnboardingInfo)).join(", ")}'.`
2021
};
2122
}
2223

@@ -112,7 +113,7 @@ expect.extend({
112113
declare global {
113114
namespace jest {
114115
interface Matchers<R> {
115-
showDeviceOnboardingCalled(deviceId: string): R;
116+
showDeviceOnboardingCalled(predicate: (deviceOnboardingInfo: DeviceOnboardingInfoDTO) => boolean): R;
116117
showDeviceOnboardingNotCalled(): R;
117118
requestAccountSelectionCalled(possibleAccountsLength: number): R;
118119
requestAccountSelectionNotCalled(): R;

packages/app-runtime/test/runtime/AppStringProcessor.test.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ArbitraryRelationshipTemplateContentJSON } from "@nmshd/content";
22
import { CoreDate } from "@nmshd/core-types";
3-
import { PeerRelationshipTemplateLoadedEvent } from "@nmshd/runtime";
3+
import { DeviceOnboardingInfoDTO, PeerRelationshipTemplateLoadedEvent } from "@nmshd/runtime";
44
import assert from "assert";
55
import { AppRuntime, LocalAccountSession } from "../../src";
66
import { MockEventBus, MockUIBridge, TestUtil } from "../lib";
@@ -216,7 +216,22 @@ describe("AppStringProcessor", function () {
216216
expect(result).toBeSuccessful();
217217
expect(result.value).toBeUndefined();
218218

219-
expect(mockUiBridge).showDeviceOnboardingCalled(deviceResult.value.id);
219+
expect(mockUiBridge).showDeviceOnboardingCalled((deviceOnboardingInfo: DeviceOnboardingInfoDTO) => deviceOnboardingInfo.id === deviceResult.value.id);
220+
});
221+
222+
test("backup device onboarding with a password protected Token", async function () {
223+
const tokenResult = await runtime1Session.transportServices.identityRecoveryKits.createIdentityRecoveryKit({
224+
profileName: "profileNameForBackupDevice",
225+
passwordProtection: { password: "password" }
226+
});
227+
228+
mockUiBridge.setPasswordToReturnForAttempt(1, "password");
229+
230+
const result = await runtime2.stringProcessor.processTruncatedReference(tokenResult.value.truncatedReference);
231+
expect(result).toBeSuccessful();
232+
expect(result.value).toBeUndefined();
233+
234+
expect(mockUiBridge).showDeviceOnboardingCalled((deviceOnboardingInfo: DeviceOnboardingInfoDTO) => deviceOnboardingInfo.isBackupDevice === true);
220235
});
221236
});
222237
});

packages/runtime/src/types/transport/DeviceOnboardingInfoDTO.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ export interface DeviceOnboardingInfoDTO {
1414
identity: IdentityDTO;
1515
password: string;
1616
username: string;
17+
isBackupDevice?: boolean;
1718
}

packages/runtime/src/useCases/transport/devices/DeviceMapper.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ export class DeviceMapper {
4141
},
4242
password: deviceSharedSecret.password,
4343
username: deviceSharedSecret.username,
44-
profileName: deviceSharedSecret.profileName
44+
profileName: deviceSharedSecret.profileName,
45+
isBackupDevice: deviceSharedSecret.isBackupDevice
4546
};
4647
}
4748

@@ -62,7 +63,8 @@ export class DeviceMapper {
6263
},
6364
password: deviceOnboardingDTO.password,
6465
username: deviceOnboardingDTO.username,
65-
profileName: deviceOnboardingDTO.profileName
66+
profileName: deviceOnboardingDTO.profileName,
67+
isBackupDevice: deviceOnboardingDTO.isBackupDevice
6668
});
6769
return sharedSecret;
6870
}

packages/transport/src/modules/devices/DeviceSecretController.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ export class DeviceSecretController extends TransportController {
142142
identityPrivateKey: identityPrivateKey?.secret as CryptoSignaturePrivateKey,
143143
username: device.username,
144144
password: device.initialPassword!,
145-
identity: this.parent.identity.identity
145+
identity: this.parent.identity.identity,
146+
isBackupDevice: device.isBackupDevice
146147
});
147148

148149
return deviceSharedSecret;

packages/transport/src/modules/devices/transmission/DeviceSharedSecret.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export interface IDeviceSharedSecret extends ISerializable {
1717
identity: IIdentity;
1818
password: string;
1919
username: string;
20+
isBackupDevice?: boolean;
2021
}
2122

2223
@type("DeviceSharedSecret")
@@ -73,6 +74,10 @@ export class DeviceSharedSecret extends Serializable implements IDeviceSharedSec
7374
@validate()
7475
public password: string;
7576

77+
@serialize()
78+
@validate({ nullable: true })
79+
public isBackupDevice?: boolean;
80+
7681
public static from(value: IDeviceSharedSecret): DeviceSharedSecret {
7782
return this.fromAny(value);
7883
}

0 commit comments

Comments
 (0)