diff --git a/packages/app-runtime/src/multiAccount/MultiAccountController.ts b/packages/app-runtime/src/multiAccount/MultiAccountController.ts index 4be81a11b..827254b99 100644 --- a/packages/app-runtime/src/multiAccount/MultiAccountController.ts +++ b/packages/app-runtime/src/multiAccount/MultiAccountController.ts @@ -197,6 +197,18 @@ export class MultiAccountController { const updatedLocalAccount = await this.updateLocalAccountAddress(localAccount.id, accountController.identity.address); + if (deviceSharedSecret.isBackupDevice) { + const tokens = await accountController.tokens.getTokens({ + "cache.content.@type": "TokenContentDeviceSharedSecret", + "cache.content.sharedSecret.id": deviceSharedSecret.id.toString(), + "cache.content.sharedSecret.isBackupDevice": true + }); + + for (const token of tokens) { + await accountController.tokens.delete(token); + } + } + return [updatedLocalAccount, accountController]; } diff --git a/packages/app-runtime/test/runtime/Onboarding.test.ts b/packages/app-runtime/test/runtime/Onboarding.test.ts index 2e9a0b043..a13533aab 100644 --- a/packages/app-runtime/test/runtime/Onboarding.test.ts +++ b/packages/app-runtime/test/runtime/Onboarding.test.ts @@ -6,6 +6,7 @@ import { TestUtil } from "../lib"; describe("Onboarding", function () { let runtime: AppRuntime; let runtime2: AppRuntime; + let runtime3: AppRuntime; let services1: AppRuntimeServices; @@ -18,6 +19,9 @@ describe("Onboarding", function () { runtime2 = await TestUtil.createRuntime(); await runtime2.start(); + + runtime3 = await TestUtil.createRuntime(); + await runtime3.start(); }); afterAll(async function () { @@ -32,7 +36,7 @@ describe("Onboarding", function () { await expect(() => runtime.accountServices.onboardAccount(onboardingInfoResult.value)).rejects.toThrow("error.app-runtime.onboardedAccountAlreadyExists"); }); - test("should onboard with a recovery kit and be able to create a new recovery kit", async () => { + test("should onboard with a recovery kit and meanwhile delete the token", async () => { const recoveryKitResponse = await services1.transportServices.identityRecoveryKits.createIdentityRecoveryKit({ profileName: "profileName", passwordProtection: { password: "aPassword" } @@ -44,7 +48,28 @@ describe("Onboarding", function () { const result = await runtime2.accountServices.onboardAccount(deviceOnboardingDTO); expect(result.address!).toBe((await services1.transportServices.account.getIdentityInfo()).value.address); - const services2 = await runtime2.getServices(result.id); + const anonymousTokenResponse = await runtime2.anonymousServices.tokens.loadPeerToken({ reference: recoveryKitResponse.value.truncatedReference, password: "aPassword" }); + expect(anonymousTokenResponse).toBeAnError( + "Token not found. Make sure the ID exists and the record is not expired. If a password is required to fetch the record, make sure you passed the correct one.", + "error.runtime.recordNotFound" + ); + + await services1.transportServices.account.syncDatawallet(); + }); + + test("should onboard with a recovery kit and be able to create a new recovery kit", async () => { + const recoveryKitResponse = await services1.transportServices.identityRecoveryKits.createIdentityRecoveryKit({ + profileName: "profileName", + passwordProtection: { password: "aPassword" } + }); + + const token = await runtime3.anonymousServices.tokens.loadPeerToken({ reference: recoveryKitResponse.value.truncatedReference, password: "aPassword" }); + const deviceOnboardingDTO = DeviceMapper.toDeviceOnboardingInfoDTO(DeviceSharedSecret.from(token.value.content.sharedSecret)); + + const result = await runtime3.accountServices.onboardAccount(deviceOnboardingDTO); + expect(result.address!).toBe((await services1.transportServices.account.getIdentityInfo()).value.address); + + const services2 = await runtime3.getServices(result.id); await services1.transportServices.account.syncDatawallet(); const devices = (await services1.transportServices.devices.getDevices()).value;