From a83ecbad22db99ff1ae69371f89118f57135f1c8 Mon Sep 17 00:00:00 2001 From: jeyem Date: Tue, 12 Nov 2024 19:59:49 +0330 Subject: [PATCH] feat(backup): introduce new schema to minimize backup length This commit adds a new backup schema designed to reduce the overall length of backups. The new schema is implemented in version 0.0.2, enhancing efficiency and reducing storage requirements. Signed-off-by: Ehsan Mahmoudi --- src/domain/backup/index.ts | 11 +- src/domain/backup/v0_0_2.ts | 45 ++ src/domain/buildingBlocks/Pluto.ts | 2 +- src/pluto/Pluto.ts | 5 +- src/pluto/backup/BackupManager.ts | 14 +- src/pluto/backup/versions/0_0_1/Backup.ts | 1 - src/pluto/backup/versions/0_0_2/Backup.ts | 97 +++ src/pluto/backup/versions/0_0_2/Restore.ts | 91 +++ src/pluto/backup/versions/0_0_2/index.ts | 2 + src/pluto/backup/versions/index.ts | 3 +- tests/pluto/Pluto.Backup.test.ts | 712 +++++++++++---------- 11 files changed, 628 insertions(+), 355 deletions(-) create mode 100644 src/domain/backup/v0_0_2.ts create mode 100644 src/pluto/backup/versions/0_0_2/Backup.ts create mode 100644 src/pluto/backup/versions/0_0_2/Restore.ts create mode 100644 src/pluto/backup/versions/0_0_2/index.ts diff --git a/src/domain/backup/index.ts b/src/domain/backup/index.ts index c926d91e4..917361f14 100644 --- a/src/domain/backup/index.ts +++ b/src/domain/backup/index.ts @@ -1,10 +1,17 @@ import { Schema as v0_0_1 } from "./v0_0_1"; +import { Schema as v0_0_2 } from "./v0_0_2"; /** * All supported backup schemas */ -export type Schema = v0_0_1; +export type Schema = v0_0_1 | v0_0_2; +export type Version = "0.0.1" | "0.0.2"; export const defaultVersion = "0.0.1"; -export { v0_0_1 }; +export const versions: Version[] = [ + "0.0.1", + "0.0.2", +]; + +export { v0_0_1, v0_0_2 }; diff --git a/src/domain/backup/v0_0_2.ts b/src/domain/backup/v0_0_2.ts new file mode 100644 index 000000000..493d8aa36 --- /dev/null +++ b/src/domain/backup/v0_0_2.ts @@ -0,0 +1,45 @@ +/** + * Schema definition for Backup V0.0.2 + */ +import * as TB from "@sinclair/typebox"; + +const credential = TB.Object({ + recovery_id: TB.String(), + data: TB.String(), +}); + +const did = TB.Object({ + did: TB.String(), + alias: TB.Optional(TB.String()), +}); + +const didpair = TB.Object({ + holder: TB.String(), + recipient: TB.String(), + alias: TB.String(), +}); + +const key = TB.Object({ + recovery_id: TB.String(), + key: TB.String(), + did: TB.Optional(TB.String()), + index: TB.Optional(TB.Number()), +}); + + +export const Schema = TB.Object({ + version: TB.Optional(TB.Literal("0.0.2")), + credentials: TB.Array(credential), + dids: TB.Array(did), + did_pairs: TB.Array(didpair), + keys: TB.Array(key), +}); + +export type Schema = TB.Static; + +export namespace Schema { + export type Credential = TB.Static; + export type DID = TB.Static; + export type DIDPair = TB.Static; + export type Key = TB.Static; +} diff --git a/src/domain/buildingBlocks/Pluto.ts b/src/domain/buildingBlocks/Pluto.ts index 950b681ff..cc9da685a 100644 --- a/src/domain/buildingBlocks/Pluto.ts +++ b/src/domain/buildingBlocks/Pluto.ts @@ -41,7 +41,7 @@ export interface Pluto { /** * create a Backup object from the stored data */ - backup(): Promise; + backup(version?: Backup.Version): Promise; /** * load the given data into the store diff --git a/src/pluto/Pluto.ts b/src/pluto/Pluto.ts index e6fa65597..bb4328d65 100644 --- a/src/pluto/Pluto.ts +++ b/src/pluto/Pluto.ts @@ -5,6 +5,7 @@ import { PeerDID } from "../peer-did/PeerDID"; import { BackupManager } from "./backup/BackupManager"; import { PlutoRepositories, repositoryFactory } from "./repositories"; import { Arrayable, asArray } from "../utils"; +import { Version } from "../domain/backup"; /** @@ -121,8 +122,8 @@ export class Pluto implements Domain.Pluto { } /** Backups **/ - backup() { - return this.BackupMgr.backup(); + backup(version?: Version) { + return this.BackupMgr.backup(version); } restore(backup: Domain.Backup.Schema) { diff --git a/src/pluto/backup/BackupManager.ts b/src/pluto/backup/BackupManager.ts index e7252c2ef..8fa23e09f 100644 --- a/src/pluto/backup/BackupManager.ts +++ b/src/pluto/backup/BackupManager.ts @@ -4,6 +4,7 @@ import { Pluto } from "../Pluto"; import { PlutoRepositories } from "../repositories"; import { isEmpty } from "../../utils"; import { IBackupTask, IRestoreTask } from "./versions/interfaces"; +import { Version } from "../../domain/backup"; /** * BackupManager @@ -21,7 +22,7 @@ export class BackupManager { * @param version - backup schema version * @returns {Promise} */ - backup(version?: string) { + backup(version?: Version) { const task = this.getBackupTask(version); return task.run(); } @@ -37,21 +38,24 @@ export class BackupManager { await task.run(); } - private getBackupTask(version: string = Domain.Backup.defaultVersion): IBackupTask { + private getBackupTask(version: Version = Domain.Backup.defaultVersion): IBackupTask { switch (version) { case "0.0.1": return new Versions.v0_0_1.BackupTask(this.Pluto, this.Repositories); + case "0.0.2": + return new Versions.v0_0_2.BackupTask(this.Pluto, this.Repositories); } throw new Domain.PlutoError.BackupNotFoundError(); } private getRestoreTask(backup: Domain.Backup.Schema): IRestoreTask { - const version = backup.version ?? Domain.Backup.defaultVersion; - - switch (version) { + backup.version = backup.version ?? Domain.Backup.defaultVersion; + switch (backup.version) { case "0.0.1": return new Versions.v0_0_1.RestoreTask(this.Pluto, backup); + case "0.0.2": + return new Versions.v0_0_2.RestoreTask(this.Pluto, backup); } throw new Domain.PlutoError.RestoreNotFoundError(); diff --git a/src/pluto/backup/versions/0_0_1/Backup.ts b/src/pluto/backup/versions/0_0_1/Backup.ts index cb4f35433..e1dc8b171 100644 --- a/src/pluto/backup/versions/0_0_1/Backup.ts +++ b/src/pluto/backup/versions/0_0_1/Backup.ts @@ -68,7 +68,6 @@ export class BackupTask implements IBackupTask { index: key.index, did: did?.uuid, }; - return acc.concat(backup); } diff --git a/src/pluto/backup/versions/0_0_2/Backup.ts b/src/pluto/backup/versions/0_0_2/Backup.ts new file mode 100644 index 000000000..ba1136cc5 --- /dev/null +++ b/src/pluto/backup/versions/0_0_2/Backup.ts @@ -0,0 +1,97 @@ +import * as Domain from "../../../../domain"; +import * as Models from "../../../models"; +import { JWTVerifiableCredentialRecoveryId } from "../../../../pollux/models/JWTVerifiableCredential"; +import { repositoryFactory } from "../../../repositories/builders/factory"; +import { IBackupTask } from "../interfaces"; +import { SDJWTVerifiableCredentialRecoveryId } from "../../../../pollux/models/SDJWTVerifiableCredential"; +import { base64url } from "multiformats/bases/base64"; + +export class BackupTask implements IBackupTask { + constructor( + private readonly Pluto: Domain.Pluto, + private readonly Repositories: ReturnType + ) {} + + async run(): Promise { + const credentials = await this.getCredentialBackups(); + const didModels = await this.Repositories.DIDs.getModels(); + const dids = didModels.map(this.mapDid); + const did_pairs = await this.getDidPairBackups(); + const keys = await this.getKeyBackups(didModels); + + const json: Domain.Backup.v0_0_2 = { + version: "0.0.2", + credentials, + dids, + did_pairs, + keys, + }; + + return json; + } + + async getCredentialBackups(): Promise { + const credentialModels = await this.Repositories.Credentials.getModels(); + return credentialModels.map(this.mapCredential); + } + + async getDidPairBackups(): Promise { + const pairLinks = await this.Repositories.DIDLinks.getModels({ selector: { role: Models.DIDLink.role.pair } }); + const didTuples = pairLinks.map(link => ({ + alias: link.alias ?? "", + holder: link.hostId, + recipient: link.targetId + })); + + return didTuples; + } + + async getKeyBackups(didModels: Models.DID[]): Promise { + const keys = await this.Repositories.Keys.get(); + const didKeyLinks = await this.Repositories.DIDKeyLinks.getModels(); + + const backupKeys = keys.reduce((acc, key) => { + if (key.isExportable() && key.isStorable()) { + const keyLink = didKeyLinks.find(x => x.keyId === key.uuid); + const did = didModels.find(x => x.uuid === keyLink?.didId); + const jwk = key.to.JWK(); + + const backup: Domain.Backup.v0_0_1.Key = { + recovery_id: key.recoveryId, + key: base64url.baseEncode(Buffer.from(JSON.stringify(jwk))), + index: key.index, + did: did?.uuid, + }; + return acc.concat(backup); + } + + return acc; + }, []); + + return backupKeys; + } + + async getLinkSecretBackup(): Promise { + const linksecret = await this.Repositories.LinkSecrets.findOne(); + + return linksecret?.secret ?? undefined; + } + + + private mapCredential = (model: Models.Credential): Domain.Backup.v0_0_1.Credential => { + const isJWT = model.recoveryId === JWTVerifiableCredentialRecoveryId; + const isSDJWT = model.recoveryId === SDJWTVerifiableCredentialRecoveryId; + const recoveryId = isJWT ? "jwt" : isSDJWT ? "sdjwt" : "anoncred"; + const data = isJWT || isSDJWT ? JSON.parse(model.dataJson).id : model.dataJson; + + return { + recovery_id: recoveryId, + data: base64url.baseEncode(Buffer.from(data)), + }; + }; + + private mapDid = (model: Models.DID): Domain.Backup.v0_0_1.DID => ({ + did: model.uuid, + alias: model.alias + }); +} diff --git a/src/pluto/backup/versions/0_0_2/Restore.ts b/src/pluto/backup/versions/0_0_2/Restore.ts new file mode 100644 index 000000000..91d808181 --- /dev/null +++ b/src/pluto/backup/versions/0_0_2/Restore.ts @@ -0,0 +1,91 @@ +import * as Domain from "../../../../domain"; +import { Ed25519PrivateKey } from "../../../../apollo/utils/Ed25519PrivateKey"; +import { Secp256k1PrivateKey } from "../../../../apollo/utils/Secp256k1PrivateKey"; +import { X25519PrivateKey } from "../../../../apollo/utils/X25519PrivateKey"; +import { AnonCredsCredential } from "../../../../pollux/models/AnonCredsVerifiableCredential"; +import { JWTCredential } from "../../../../pollux/models/JWTVerifiableCredential"; +import { notEmptyString, notNil, validate } from "../../../../utils"; +import { IRestoreTask } from "../interfaces"; +import { base64url } from "multiformats/bases/base64"; + +export class RestoreTask implements IRestoreTask { + constructor( + private readonly Pluto: Domain.Pluto, + private readonly backup: Domain.Backup.v0_0_2, + ) { } + + async run(): Promise { + validate(this.backup, Domain.Backup.v0_0_2); + await this.restoreCredentials(); + await this.restoreDids(); + await this.restoreDidPairs(); + await this.restoreKeys(); + } + + async restoreCredentials() { + const credentials = this.backup.credentials.map(item => { + const decoded = Buffer.from(base64url.baseDecode(item.data)).toString() + if (item.recovery_id === "jwt") { + return JWTCredential.fromJWS(decoded); + } + if (item.recovery_id === "anoncred") { + return AnonCredsCredential.fromJson(decoded); + } + throw new Domain.PlutoError.RestoreCredentialInvalidError(); + }); + + await Promise.all(credentials.map(x => this.Pluto.storeCredential(x))); + } + + async restoreDids() { + await Promise.all( + this.backup.dids.map(x => this.Pluto.storeDID(Domain.DID.from(x.did), [], x.alias)) + ); + } + + async restoreDidPairs() { + await Promise.all( + this.backup.did_pairs.map(item => { + const host = Domain.DID.from(item.holder); + const target = Domain.DID.from(item.recipient); + return this.Pluto.storeDIDPair(host, target, item.alias); + }) + ); + } + + async restoreKeys() { + return Promise.all(this.backup.keys.map(item => { + + const jwk = JSON.parse(Buffer.from(base64url.baseDecode(item.key)).toString()); + const key = this.jwkToDomain(jwk); + if (notNil(item.index)) { + key.keySpecification.set(Domain.KeyProperties.index, item.index.toString()); + } + if (notEmptyString(item.did)) { + return this.Pluto.storeDID(Domain.DID.from(item.did), key); + } else { + return this.Pluto.storePrivateKey(key); + } + }) + ) + } + + private jwkToDomain(jwk: Domain.JWK): Domain.PrivateKey { + if ((jwk.kty === "OKP" || jwk.kty === "EC") && notEmptyString(jwk.d)) { + switch (jwk.crv) { + case Domain.Curve.SECP256K1.toLowerCase(): + return Secp256k1PrivateKey.from.String(jwk.d, "base64url"); + + case Domain.Curve.ED25519: + return Ed25519PrivateKey.from.String(jwk.d, "base64url"); + + case Domain.Curve.X25519: + return X25519PrivateKey.from.String(jwk.d, "base64url"); + } + + throw new Domain.PlutoError.RestoreKeyInvalidError(); + } + + throw new Domain.PlutoError.RestoreJWKInvalidError(); + } +} diff --git a/src/pluto/backup/versions/0_0_2/index.ts b/src/pluto/backup/versions/0_0_2/index.ts new file mode 100644 index 000000000..9bf29dabe --- /dev/null +++ b/src/pluto/backup/versions/0_0_2/index.ts @@ -0,0 +1,2 @@ +export * from "./Backup"; +export * from "./Restore"; diff --git a/src/pluto/backup/versions/index.ts b/src/pluto/backup/versions/index.ts index e78f30a59..9f73ac8b0 100644 --- a/src/pluto/backup/versions/index.ts +++ b/src/pluto/backup/versions/index.ts @@ -1,3 +1,4 @@ import * as v0_0_1 from "./0_0_1"; +import * as v0_0_2 from "./0_0_2"; -export { v0_0_1 }; +export { v0_0_1, v0_0_2 }; diff --git a/tests/pluto/Pluto.Backup.test.ts b/tests/pluto/Pluto.Backup.test.ts index afed2abda..3f3ed6d5a 100644 --- a/tests/pluto/Pluto.Backup.test.ts +++ b/tests/pluto/Pluto.Backup.test.ts @@ -9,6 +9,8 @@ import * as Fixtures from "../fixtures"; import { mockPluto } from "../fixtures/inmemory/factory"; import { AnonCredsCredential, JWTCredential } from "../../src"; import { base64url } from 'multiformats/bases/base64'; +import { versions } from '../../src/domain/backup'; +import { backup } from 'rxdb/plugins/backup'; describe("Pluto", () => { let instance: Domain.Pluto; @@ -18,380 +20,404 @@ describe("Pluto", () => { await instance.start(); }); - describe("Backup", () => { - test("default - no values", async () => { - const result = await instance.backup(); - - expect(result).not.to.be.null; - expect(result).to.have.property("credentials").to.be.an("array").to.have.length(0); - expect(result).to.have.property("dids").to.be.an("array").to.have.length(0); - expect(result).to.have.property("did_pairs").to.be.an("array").to.have.length(0); - expect(result).to.have.property("keys").to.be.an("array").to.have.length(0); - expect(result).to.have.property("messages").to.be.an("array").to.have.length(0); - expect(result).to.have.property("link_secret").to.be.undefined; - }); - - test("credential - JWT", async () => { - await instance.storeCredential(Fixtures.Backup.credentialJWT); - // await instance.storeCredential(Fixtures.Backup.credentialAnoncreds); - - const result = await instance.backup(); - - expect(result.credentials).to.be.an("array").to.have.length(1); - expect(result.credentials[0]).to.have.property("recovery_id", "jwt"); - const expectedData = Buffer.from(base64url.baseEncode(Buffer.from(Fixtures.Backup.credentialJWT.id))).toString(); - expect(result.credentials[0]).to.have.property("data", expectedData); - }); - - test("dids + did_pairs", async () => { - await instance.storeDIDPair(Fixtures.Backup.hostDID, Fixtures.Backup.targetDID, Fixtures.Backup.pairAlias); - - const result = await instance.backup(); - - expect(result.dids).to.be.an("array").to.have.length(2); - expect(result.dids).to.include.deep.members([ - { did: Fixtures.Backup.hostDID.toString(), alias: undefined }, - { did: Fixtures.Backup.targetDID.toString(), alias: undefined }, - ]); - - expect(result.did_pairs).to.be.an("array").to.have.length(1); - expect(result.did_pairs).to.include.deep.members([ - { - alias: Fixtures.Backup.pairAlias, - holder: Fixtures.Backup.hostDID.toString(), - recipient: Fixtures.Backup.targetDID.toString(), - }, - ]); - }); - - test("keys", async () => { - // await instance.storePrivateKey() - await instance.storeDID(Fixtures.Backup.hostDID, Fixtures.Backup.peerDIDKeys); - - const result = await instance.backup(); - - expect(result.keys).to.be.an("array").to.have.length(1); - - const expectedKey = Buffer.from( - - base64url.baseEncode( - Buffer.from( - JSON.stringify(Fixtures.Backup.peerDIDKeys[0].to.JWK()) - ) - ) - - ).toString(); - expect(result.keys[0]).to.have.property("key", expectedKey); - expect(result.keys[0]).to.have.property("index", Fixtures.Backup.peerDIDKeys[0].index); - expect(result.keys[0]).to.have.property("did", Fixtures.Backup.hostDID.toString()); - }); - - test("link_secret", async () => { - await instance.storeLinkSecret(Fixtures.Backup.linkSecret); - - const result = await instance.backup(); - - expect(result.link_secret).to.be.a("string"); - expect(result.link_secret).to.eql(Fixtures.Backup.linkSecret.secret); - }); - - test("mediators", async () => { - await instance.storeMediator(Fixtures.Backup.mediator); - const result = await instance.backup(); - - expect(result.mediators).to.be.an("array").to.have.length(1); - }); - - test("messages", async () => { - await instance.storeMessage(Fixtures.Backup.message); - const result = await instance.backup(); - - expect(result.messages).to.be.an("array").to.have.length(1); - }); - }); - - describe("Restore", () => { - test("credentials - JWT", async () => { - await instance.restore({ - credentials: [ - { - recovery_id: 'jwt', - data: Buffer.from(base64url.baseEncode(Buffer.from(Fixtures.Credentials.JWT.credentialPayloadEncoded))).toString(), - }, - ], - dids: [], - did_pairs: [], - keys: [], - mediators: [], - messages: [], - link_secret: undefined, + versions.forEach(version => { + + describe(`Backup ${version}`, () => { + test("default - no values", async () => { + const result = await instance.backup(version); + + expect(result).not.to.be.null; + expect(result).to.have.property("credentials").to.be.an("array").to.have.length(0); + expect(result).to.have.property("dids").to.be.an("array").to.have.length(0); + expect(result).to.have.property("did_pairs").to.be.an("array").to.have.length(0); + if (version == "0.0.1") { + expect(result).to.have.property("keys").to.be.an("array").to.have.length(0); + expect(result).to.have.property("messages").to.be.an("array").to.have.length(0); + expect(result).to.have.property("link_secret").to.be.undefined; + } }); - const result = await instance.getAllCredentials(); - expect(result).to.be.an("array").to.have.length(1); - const sut = result[0] as JWTCredential; - expect(sut.audience).to.eq(Fixtures.Backup.credentialJWT.audience); - expect(sut.claims).to.deep.eq(Fixtures.Backup.credentialJWT.claims); - expect(sut.context).to.deep.eq(Fixtures.Backup.credentialJWT.context); - expect(sut.credentialSchema).to.deep.eq(Fixtures.Backup.credentialJWT.credentialSchema); - expect(sut.credentialStatus).to.deep.eq(Fixtures.Backup.credentialJWT.credentialStatus); - expect(sut.credentialSubject).to.deep.eq(Fixtures.Backup.credentialJWT.credentialSubject); - expect(sut.credentialType).to.eq(Fixtures.Backup.credentialJWT.credentialType); - expect(sut.evidence).to.deep.eq(Fixtures.Backup.credentialJWT.evidence); - expect(sut.expirationDate).to.eq(Fixtures.Backup.credentialJWT.expirationDate); - expect(sut.id).to.eq(Fixtures.Backup.credentialJWT.id); - expect(sut.issuanceDate).to.eq(Fixtures.Backup.credentialJWT.issuanceDate); - expect(sut.issuer).to.eq(Fixtures.Backup.credentialJWT.issuer); - expect(sut.properties).to.deep.eq(Fixtures.Backup.credentialJWT.properties); - expect(sut.recoveryId).to.eq(Fixtures.Backup.credentialJWT.recoveryId); - expect(sut.refreshService).to.eq(Fixtures.Backup.credentialJWT.refreshService); - expect(sut.subject).to.eq(Fixtures.Backup.credentialJWT.subject); - expect(sut.termsOfUse).to.deep.eq(Fixtures.Backup.credentialJWT.termsOfUse); - expect(sut.type).to.deep.eq(Fixtures.Backup.credentialJWT.type); - }); - - test("credentials - Anoncreds", async () => { - await instance.restore({ - credentials: [ - { - recovery_id: "anoncred", - data: Buffer.from(base64url.baseEncode(Buffer.from(Fixtures.Backup.credentialAnoncreds.toStorable().credentialData))).toString() - }, - ], - dids: [], - did_pairs: [], - keys: [], - mediators: [], - messages: [], - link_secret: undefined, - }); + test("credential - JWT", async () => { + await instance.storeCredential(Fixtures.Backup.credentialJWT); + // await instance.storeCredential(Fixtures.Backup.credentialAnoncreds); - const result = await instance.getAllCredentials(); - expect(result).to.be.an("array").to.have.length(1); - const sut = result[0] as AnonCredsCredential; - expect(sut.claims).to.deep.eq(Fixtures.Backup.credentialAnoncreds.claims); - expect(sut.credentialDefinitionId).to.eq(Fixtures.Backup.credentialAnoncreds.credentialDefinitionId); - expect(sut.credentialType).to.eq(Fixtures.Backup.credentialAnoncreds.credentialType); - expect(sut.id).to.eq(Fixtures.Backup.credentialAnoncreds.id); - expect(sut.issuer).to.eq(Fixtures.Backup.credentialAnoncreds.issuer); - expect(sut.properties).to.deep.eq(Fixtures.Backup.credentialAnoncreds.properties); - expect(sut.recoveryId).to.eq(Fixtures.Backup.credentialAnoncreds.recoveryId); - expect(sut.schemaId).to.eq(Fixtures.Backup.credentialAnoncreds.schemaId); - expect(sut.subject).to.eq(Fixtures.Backup.credentialAnoncreds.subject); - }); + const result = await instance.backup(version); - test("dids", async () => { - await instance.restore({ - credentials: [], - dids: [ - { did: Fixtures.Backup.hostDID.toString() }, - ], - did_pairs: [], - keys: [], - mediators: [], - messages: [], - link_secret: undefined, + expect(result.credentials).to.be.an("array").to.have.length(1); + expect(result.credentials[0]).to.have.property("recovery_id", "jwt"); + const expectedData = Buffer.from(base64url.baseEncode(Buffer.from(Fixtures.Backup.credentialJWT.id))).toString(); + expect(result.credentials[0]).to.have.property("data", expectedData); }); - const result = await (instance as any).Repositories.DIDs.get(); + test("dids + did_pairs", async () => { + await instance.storeDIDPair(Fixtures.Backup.hostDID, Fixtures.Backup.targetDID, Fixtures.Backup.pairAlias); - expect(result).to.be.an("array").to.have.length(1); - expect(result[0].toString()).to.eq(Fixtures.Backup.hostDID.toString()); - }); + const result = await instance.backup(version); + + expect(result.dids).to.be.an("array").to.have.length(2); + expect(result.dids).to.include.deep.members([ + { did: Fixtures.Backup.hostDID.toString(), alias: undefined }, + { did: Fixtures.Backup.targetDID.toString(), alias: undefined }, + ]); - test("did_pairs", async () => { - const name = "test-did-pairs"; - await instance.restore({ - credentials: [], - dids: [], - did_pairs: [ + expect(result.did_pairs).to.be.an("array").to.have.length(1); + expect(result.did_pairs).to.include.deep.members([ { - alias: name, + alias: Fixtures.Backup.pairAlias, holder: Fixtures.Backup.hostDID.toString(), recipient: Fixtures.Backup.targetDID.toString(), - } - ], - keys: [], - mediators: [], - messages: [], - link_secret: undefined, + }, + ]); }); - const result = await instance.getAllDidPairs(); + test("keys", async () => { + // await instance.storePrivateKey() + await instance.storeDID(Fixtures.Backup.hostDID, Fixtures.Backup.peerDIDKeys); - expect(result).to.be.an("array").to.have.length(1); - expect(result[0].host.toString()).to.eq(Fixtures.Backup.hostDID.toString()); - expect(result[0].receiver.toString()).to.eq(Fixtures.Backup.targetDID.toString()); - expect(result[0].name).to.eq(name); - }); + const result = await instance.backup(version); - test("keys", async () => { - await instance.restore({ - credentials: [], - dids: [], - did_pairs: [], - keys: [ - { - recovery_id: Fixtures.Backup.secpPrivateKey.recoveryId, - key: Buffer.from(base64url.baseEncode(Buffer.from(JSON.stringify(Fixtures.Backup.secpPrivateKey.to.JWK())))).toString(), - } - ], - mediators: [], - messages: [], - link_secret: undefined, - }); + expect(result.keys).to.be.an("array").to.have.length(1); - const result = await (instance as any).Repositories.Keys.get(); + const expectedKey = Buffer.from( - expect(result).to.be.an("array").to.have.length(1); - expect(result[0].curve).to.eq(Fixtures.Backup.secpPrivateKey.curve); - expect(result[0].index).to.eq(Fixtures.Backup.secpPrivateKey.index); - expect(result[0].keySpecification).to.deep.eq(Fixtures.Backup.secpPrivateKey.keySpecification); - expect(result[0].raw).to.deep.eq(Fixtures.Backup.secpPrivateKey.raw); - expect(result[0].recoveryId).to.eq(Fixtures.Backup.secpPrivateKey.recoveryId); - expect(result[0].size).to.eq(Fixtures.Backup.secpPrivateKey.size); - expect(result[0].type).to.eq(Fixtures.Backup.secpPrivateKey.type); - }); + base64url.baseEncode( + Buffer.from( + JSON.stringify(Fixtures.Backup.peerDIDKeys[0].to.JWK()) + ) + ) - test("messages", async () => { - await instance.restore({ - credentials: [], - dids: [], - did_pairs: [], - keys: [], - mediators: [], - messages: [ - "eyJpZCI6IjMwZmIyNTU1LWM5YjgtNDExZC1hOTY2LTg0ZmMwOGJiMWVmZCIsImJvZHkiOnsiY29udGVudCI6IlRlc3QgTWVzc2FnZSJ9LCJwaXVyaSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvYmFzaWNtZXNzYWdlLzIuMC9tZXNzYWdlIiwiZnJvbSI6ImRpZDpwZWVyOjIuRXo2TFNieXVFOTVXQUpZaFFhcEhSVnVSbTZLTEdiYjc5ZjVVWGlhWVRBWXBVYlpnZC5WejZNa2s0U1l6TER0WkpudVJOMlZKNGtuWmN1SlU0bzVDYjlVVURodkF0YVVaQ3g3LlNleUowSWpvaVpHMGlMQ0p6SWpwN0luVnlhU0k2SW1ScFpEcHdaV1Z5T2pJdVJYbzJURk5uYUhkVFJUUXpOM2R1UkVVeGNIUXpXRFpvVmtSVlVYcFRhbk5JZW1sdWNGZ3pXRVoyVFdwU1FXMDNlUzVXZWpaTmEyaG9NV1UxUTBWWldYRTJTa0pWWTFSYU5rTndNbkpoYmtOWFVuSjJOMWxoZUROTVpUUk9OVGxTTm1Sa0xsTmxlVW93U1dwdmFWcEhNR2xNUTBwNlNXcHdOMGx1Vm5saFUwazJTVzFvTUdSSVFucFBhVGgyWXpKc01FeFlRbmxoV0U1MFRGY3hiRnBIYkdoa1J6bDVURzFHTUZsWGVHaGpTRXB3WXpJd2RXRlhPR2xNUTBwb1NXcHdZa2x0VW5CYVIwNTJZbGN3ZG1ScVNXbFlXREU1TGxObGVVb3dTV3B2YVZwSE1HbE1RMHA2U1dwd04wbHVWbmxoVTBrMlNXNWtlbU42YjNaTU0wNXdaRU14ZDJOdGJIcGlVekYwV2xkU2NGbFlVblpqYVRWb1pFZEdjMWxZUW5saFdFNTBURzFzZGt3elpIcEphWGRwV1ZOSk5sZDVTbXRoVjFKcVlqSXhkRXd6V1hsSmJERTVabEVpTENKeUlqcGJYU3dpWVNJNlcxMTlmUSIsInRvIjoiZGlkOnBlZXI6Mi5FejZMU21Zalk1Y25ISkVEM1J6YkJrb1F1RzVLd3Q5dEM3WHIyNVlCeFRmQ2FoTm9MLlZ6Nk1rdDVCNVR3d2NVaHFTVFZNWFUzV3B6cHhSTXF6WEd5VTkxeUNpZHZ2b1BvTVYuU2V5SnlJanBiWFN3aWN5STZJbVJwWkRwd1pXVnlPakl1UlhvMlRGTm5hSGRUUlRRek4zZHVSRVV4Y0hReldEWm9Wa1JWVVhwVGFuTkllbWx1Y0ZneldFWjJUV3BTUVcwM2VTNVdlalpOYTJob01XVTFRMFZaV1hFMlNrSlZZMVJhTmtOd01uSmhia05YVW5KMk4xbGhlRE5NWlRST05UbFNObVJrTGxObGVVb3dTV3B2YVZwSE1HbE1RMHA2U1dwdmFXRklVakJqU0UwMlRIazVlbUZZVVhSalNFcHdZekl3ZEdKWFZtdGhWMFl3WWpOSmRWbFlVbWhpUjBaM1kyMXNlbUpUTlhCaWVVbHpTVzVKYVU5c2RHUk1RMHBvU1dwd1lrbHRVbkJhUjA1MllsY3dkbVJxU1dsWVdEQWlMQ0poSWpwYlhTd2lkQ0k2SW1SdEluMCIsImNyZWF0ZWRUaW1lIjoxNzA5NjMzOTczNDM4LCJleHBpcmVzVGltZSI6MTcwOTYzMzk3MzQzODg2NDAwLCJhdHRhY2htZW50cyI6W10sImFjayI6W10sImRpcmVjdGlvbiI6MSwiZXh0cmFIZWFkZXJzIjp7fX0" - ], - link_secret: undefined, + ).toString(); + expect(result.keys[0]).to.have.property("key", expectedKey); + expect(result.keys[0]).to.have.property("index", Fixtures.Backup.peerDIDKeys[0].index); + expect(result.keys[0]).to.have.property("did", Fixtures.Backup.hostDID.toString()); }); + if (version == "0.0.1") { + test("link_secret", async () => { + await instance.storeLinkSecret(Fixtures.Backup.linkSecret); + + const result = await instance.backup(version); + if (result.version == '0.0.1') { + expect(result.link_secret).to.be.a("string"); + expect(result.link_secret).to.eql(Fixtures.Backup.linkSecret.secret); + } + }); - const result = await instance.getAllMessages(); + test("mediators", async () => { + await instance.storeMediator(Fixtures.Backup.mediator); + const result = await instance.backup(version); + if (result.version == '0.0.1') { + expect(result.mediators).to.be.an("array").to.have.length(1); + } + }); - expect(result).to.be.an("array").to.have.length(1); - const msg = result.at(0)!; - expect(msg.ack).to.deep.eq(Fixtures.Backup.message.ack); - expect(msg.attachments).to.deep.eq(Fixtures.Backup.message.attachments); - expect(msg.body).to.deep.eq(Fixtures.Backup.message.body); - expect(msg.createdTime).to.eq(Fixtures.Backup.message.createdTime); - expect(msg.direction).to.eq(Fixtures.Backup.message.direction); - expect(msg.expiresTimePlus).to.eq(Fixtures.Backup.message.expiresTimePlus); - expect(msg.extraHeaders).to.deep.eq(Fixtures.Backup.message.extraHeaders); - expect(msg.from?.toString()).to.eq(Fixtures.Backup.message.from?.toString()); - expect(msg.fromPrior).to.eq(Fixtures.Backup.message.fromPrior); - expect(msg.id).to.eq(Fixtures.Backup.message.id); - expect(msg.piuri).to.eq(Fixtures.Backup.message.piuri); - expect(msg.pthid).to.eq(Fixtures.Backup.message.pthid); - expect(msg.thid).to.eq(Fixtures.Backup.message.thid); - expect(msg.to?.toString()).to.eq(Fixtures.Backup.message.to?.toString()); + test("messages", async () => { + await instance.storeMessage(Fixtures.Backup.message); + const result = await instance.backup(version); + if (result.version == '0.0.1') { + expect(result.messages).to.be.an("array").to.have.length(1); + } + }); + } }); - test("link_secret", async () => { - const secret = "test123"; - await instance.restore({ - credentials: [], - dids: [], - did_pairs: [], - keys: [], - mediators: [], - messages: [], - link_secret: secret, + describe(`Restore ${version}`, () => { + test("credentials - JWT", async () => { + await instance.restore({ + version, + credentials: [ + { + recovery_id: 'jwt', + data: Buffer.from(base64url.baseEncode(Buffer.from(Fixtures.Credentials.JWT.credentialPayloadEncoded))).toString(), + }, + ], + dids: [], + did_pairs: [], + keys: [], + mediators: [], + messages: [], + link_secret: undefined, + }); + + const result = await instance.getAllCredentials(); + expect(result).to.be.an("array").to.have.length(1); + const sut = result[0] as JWTCredential; + expect(sut.audience).to.eq(Fixtures.Backup.credentialJWT.audience); + expect(sut.claims).to.deep.eq(Fixtures.Backup.credentialJWT.claims); + expect(sut.context).to.deep.eq(Fixtures.Backup.credentialJWT.context); + expect(sut.credentialSchema).to.deep.eq(Fixtures.Backup.credentialJWT.credentialSchema); + expect(sut.credentialStatus).to.deep.eq(Fixtures.Backup.credentialJWT.credentialStatus); + expect(sut.credentialSubject).to.deep.eq(Fixtures.Backup.credentialJWT.credentialSubject); + expect(sut.credentialType).to.eq(Fixtures.Backup.credentialJWT.credentialType); + expect(sut.evidence).to.deep.eq(Fixtures.Backup.credentialJWT.evidence); + expect(sut.expirationDate).to.eq(Fixtures.Backup.credentialJWT.expirationDate); + expect(sut.id).to.eq(Fixtures.Backup.credentialJWT.id); + expect(sut.issuanceDate).to.eq(Fixtures.Backup.credentialJWT.issuanceDate); + expect(sut.issuer).to.eq(Fixtures.Backup.credentialJWT.issuer); + expect(sut.properties).to.deep.eq(Fixtures.Backup.credentialJWT.properties); + expect(sut.recoveryId).to.eq(Fixtures.Backup.credentialJWT.recoveryId); + expect(sut.refreshService).to.eq(Fixtures.Backup.credentialJWT.refreshService); + expect(sut.subject).to.eq(Fixtures.Backup.credentialJWT.subject); + expect(sut.termsOfUse).to.deep.eq(Fixtures.Backup.credentialJWT.termsOfUse); + expect(sut.type).to.deep.eq(Fixtures.Backup.credentialJWT.type); }); - - const result = await instance.getLinkSecret(); - - expect(result).to.be.instanceOf(Domain.LinkSecret); - expect(result?.secret).to.eq(secret); - }); - - describe("Store not empty - throws", () => { - it("Credentials", async () => { - await instance.storeCredential(Fixtures.Backup.credentialJWT); - expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + + test("credentials - Anoncreds", async () => { + await instance.restore({ + credentials: [ + { + recovery_id: "anoncred", + data: Buffer.from(base64url.baseEncode(Buffer.from(Fixtures.Backup.credentialAnoncreds.toStorable().credentialData))).toString() + }, + ], + dids: [], + did_pairs: [], + keys: [], + mediators: [], + messages: [], + link_secret: undefined, + }); + + const result = await instance.getAllCredentials(); + expect(result).to.be.an("array").to.have.length(1); + const sut = result[0] as AnonCredsCredential; + expect(sut.claims).to.deep.eq(Fixtures.Backup.credentialAnoncreds.claims); + expect(sut.credentialDefinitionId).to.eq(Fixtures.Backup.credentialAnoncreds.credentialDefinitionId); + expect(sut.credentialType).to.eq(Fixtures.Backup.credentialAnoncreds.credentialType); + expect(sut.id).to.eq(Fixtures.Backup.credentialAnoncreds.id); + expect(sut.issuer).to.eq(Fixtures.Backup.credentialAnoncreds.issuer); + expect(sut.properties).to.deep.eq(Fixtures.Backup.credentialAnoncreds.properties); + expect(sut.recoveryId).to.eq(Fixtures.Backup.credentialAnoncreds.recoveryId); + expect(sut.schemaId).to.eq(Fixtures.Backup.credentialAnoncreds.schemaId); + expect(sut.subject).to.eq(Fixtures.Backup.credentialAnoncreds.subject); }); - - it("DIDs", async () => { - await instance.storeDIDPair(Fixtures.Backup.hostDID, Fixtures.Backup.targetDID, Fixtures.Backup.pairAlias); - expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + + test("dids", async () => { + await instance.restore({ + credentials: [], + dids: [ + { did: Fixtures.Backup.hostDID.toString() }, + ], + did_pairs: [], + keys: [], + mediators: [], + messages: [], + link_secret: undefined, + }); + + const result = await (instance as any).Repositories.DIDs.get(); + + expect(result).to.be.an("array").to.have.length(1); + expect(result[0].toString()).to.eq(Fixtures.Backup.hostDID.toString()); }); - - it("Keys", async () => { - await instance.storeDID(Fixtures.Backup.hostDID, Fixtures.Backup.peerDIDKeys); - expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + + test("did_pairs", async () => { + const name = "test-did-pairs"; + await instance.restore({ + credentials: [], + dids: [], + did_pairs: [ + { + alias: name, + holder: Fixtures.Backup.hostDID.toString(), + recipient: Fixtures.Backup.targetDID.toString(), + } + ], + keys: [], + mediators: [], + messages: [], + link_secret: undefined, + }); + + const result = await instance.getAllDidPairs(); + + expect(result).to.be.an("array").to.have.length(1); + expect(result[0].host.toString()).to.eq(Fixtures.Backup.hostDID.toString()); + expect(result[0].receiver.toString()).to.eq(Fixtures.Backup.targetDID.toString()); + expect(result[0].name).to.eq(name); }); - - it("LinkSecret", async () => { - await instance.storeLinkSecret(Fixtures.Backup.linkSecret); - expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + + test("keys", async () => { + await instance.restore({ + credentials: [], + dids: [], + did_pairs: [], + keys: [ + { + recovery_id: Fixtures.Backup.secpPrivateKey.recoveryId, + key: Buffer.from(base64url.baseEncode(Buffer.from(JSON.stringify(Fixtures.Backup.secpPrivateKey.to.JWK())))).toString(), + } + ], + mediators: [], + messages: [], + link_secret: undefined, + }); + + const result = await (instance as any).Repositories.Keys.get(); + + expect(result).to.be.an("array").to.have.length(1); + expect(result[0].curve).to.eq(Fixtures.Backup.secpPrivateKey.curve); + expect(result[0].index).to.eq(Fixtures.Backup.secpPrivateKey.index); + expect(result[0].keySpecification).to.deep.eq(Fixtures.Backup.secpPrivateKey.keySpecification); + expect(result[0].raw).to.deep.eq(Fixtures.Backup.secpPrivateKey.raw); + expect(result[0].recoveryId).to.eq(Fixtures.Backup.secpPrivateKey.recoveryId); + expect(result[0].size).to.eq(Fixtures.Backup.secpPrivateKey.size); + expect(result[0].type).to.eq(Fixtures.Backup.secpPrivateKey.type); }); - - it("Messages", async () => { - await instance.storeMessage(Fixtures.Backup.message); - expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + if (version == "0.0.1") { + test("messages", async () => { + await instance.restore({ + credentials: [], + dids: [], + did_pairs: [], + keys: [], + mediators: [], + messages: [ + "eyJpZCI6IjMwZmIyNTU1LWM5YjgtNDExZC1hOTY2LTg0ZmMwOGJiMWVmZCIsImJvZHkiOnsiY29udGVudCI6IlRlc3QgTWVzc2FnZSJ9LCJwaXVyaSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvYmFzaWNtZXNzYWdlLzIuMC9tZXNzYWdlIiwiZnJvbSI6ImRpZDpwZWVyOjIuRXo2TFNieXVFOTVXQUpZaFFhcEhSVnVSbTZLTEdiYjc5ZjVVWGlhWVRBWXBVYlpnZC5WejZNa2s0U1l6TER0WkpudVJOMlZKNGtuWmN1SlU0bzVDYjlVVURodkF0YVVaQ3g3LlNleUowSWpvaVpHMGlMQ0p6SWpwN0luVnlhU0k2SW1ScFpEcHdaV1Z5T2pJdVJYbzJURk5uYUhkVFJUUXpOM2R1UkVVeGNIUXpXRFpvVmtSVlVYcFRhbk5JZW1sdWNGZ3pXRVoyVFdwU1FXMDNlUzVXZWpaTmEyaG9NV1UxUTBWWldYRTJTa0pWWTFSYU5rTndNbkpoYmtOWFVuSjJOMWxoZUROTVpUUk9OVGxTTm1Sa0xsTmxlVW93U1dwdmFWcEhNR2xNUTBwNlNXcHdOMGx1Vm5saFUwazJTVzFvTUdSSVFucFBhVGgyWXpKc01FeFlRbmxoV0U1MFRGY3hiRnBIYkdoa1J6bDVURzFHTUZsWGVHaGpTRXB3WXpJd2RXRlhPR2xNUTBwb1NXcHdZa2x0VW5CYVIwNTJZbGN3ZG1ScVNXbFlXREU1TGxObGVVb3dTV3B2YVZwSE1HbE1RMHA2U1dwd04wbHVWbmxoVTBrMlNXNWtlbU42YjNaTU0wNXdaRU14ZDJOdGJIcGlVekYwV2xkU2NGbFlVblpqYVRWb1pFZEdjMWxZUW5saFdFNTBURzFzZGt3elpIcEphWGRwV1ZOSk5sZDVTbXRoVjFKcVlqSXhkRXd6V1hsSmJERTVabEVpTENKeUlqcGJYU3dpWVNJNlcxMTlmUSIsInRvIjoiZGlkOnBlZXI6Mi5FejZMU21Zalk1Y25ISkVEM1J6YkJrb1F1RzVLd3Q5dEM3WHIyNVlCeFRmQ2FoTm9MLlZ6Nk1rdDVCNVR3d2NVaHFTVFZNWFUzV3B6cHhSTXF6WEd5VTkxeUNpZHZ2b1BvTVYuU2V5SnlJanBiWFN3aWN5STZJbVJwWkRwd1pXVnlPakl1UlhvMlRGTm5hSGRUUlRRek4zZHVSRVV4Y0hReldEWm9Wa1JWVVhwVGFuTkllbWx1Y0ZneldFWjJUV3BTUVcwM2VTNVdlalpOYTJob01XVTFRMFZaV1hFMlNrSlZZMVJhTmtOd01uSmhia05YVW5KMk4xbGhlRE5NWlRST05UbFNObVJrTGxObGVVb3dTV3B2YVZwSE1HbE1RMHA2U1dwdmFXRklVakJqU0UwMlRIazVlbUZZVVhSalNFcHdZekl3ZEdKWFZtdGhWMFl3WWpOSmRWbFlVbWhpUjBaM1kyMXNlbUpUTlhCaWVVbHpTVzVKYVU5c2RHUk1RMHBvU1dwd1lrbHRVbkJhUjA1MllsY3dkbVJxU1dsWVdEQWlMQ0poSWpwYlhTd2lkQ0k2SW1SdEluMCIsImNyZWF0ZWRUaW1lIjoxNzA5NjMzOTczNDM4LCJleHBpcmVzVGltZSI6MTcwOTYzMzk3MzQzODg2NDAwLCJhdHRhY2htZW50cyI6W10sImFjayI6W10sImRpcmVjdGlvbiI6MSwiZXh0cmFIZWFkZXJzIjp7fX0" + ], + link_secret: undefined, + }); + + const result = await instance.getAllMessages(); + + expect(result).to.be.an("array").to.have.length(1); + const msg = result.at(0)!; + expect(msg.ack).to.deep.eq(Fixtures.Backup.message.ack); + expect(msg.attachments).to.deep.eq(Fixtures.Backup.message.attachments); + expect(msg.body).to.deep.eq(Fixtures.Backup.message.body); + expect(msg.createdTime).to.eq(Fixtures.Backup.message.createdTime); + expect(msg.direction).to.eq(Fixtures.Backup.message.direction); + expect(msg.expiresTimePlus).to.eq(Fixtures.Backup.message.expiresTimePlus); + expect(msg.extraHeaders).to.deep.eq(Fixtures.Backup.message.extraHeaders); + expect(msg.from?.toString()).to.eq(Fixtures.Backup.message.from?.toString()); + expect(msg.fromPrior).to.eq(Fixtures.Backup.message.fromPrior); + expect(msg.id).to.eq(Fixtures.Backup.message.id); + expect(msg.piuri).to.eq(Fixtures.Backup.message.piuri); + expect(msg.pthid).to.eq(Fixtures.Backup.message.pthid); + expect(msg.thid).to.eq(Fixtures.Backup.message.thid); + expect(msg.to?.toString()).to.eq(Fixtures.Backup.message.to?.toString()); + }); + } + + if (version == "0.0.1") { + test("link_secret", async () => { + const secret = "test123"; + await instance.restore({ + credentials: [], + dids: [], + did_pairs: [], + keys: [], + mediators: [], + messages: [], + link_secret: secret, + }); + + const result = await instance.getLinkSecret(); + + expect(result).to.be.instanceOf(Domain.LinkSecret); + expect(result?.secret).to.eq(secret); + }); + } + + describe("Store not empty - throws", () => { + it("Credentials", async () => { + await instance.storeCredential(Fixtures.Backup.credentialJWT); + expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + }); + + it("DIDs", async () => { + await instance.storeDIDPair(Fixtures.Backup.hostDID, Fixtures.Backup.targetDID, Fixtures.Backup.pairAlias); + expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + }); + + it("Keys", async () => { + await instance.storeDID(Fixtures.Backup.hostDID, Fixtures.Backup.peerDIDKeys); + expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + }); + + if (version == "0.0.1") { + it("LinkSecret", async () => { + await instance.storeLinkSecret(Fixtures.Backup.linkSecret); + expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + }); + + it("Messages", async () => { + await instance.storeMessage(Fixtures.Backup.message); + expect(instance.restore(Fixtures.Backup.backupJson)).eventually.rejected; + }); + } }); }); - }); - - describe("Round trip", () => { - test("Restore -> Backup", async () => { - await instance.restore(Fixtures.Backup.backupJson); - - const backup = await instance.backup(); - - expect(backup.credentials).to.have.length(Fixtures.Backup.backupJson.credentials.length); - expect(backup.credentials).to.have.deep.members(Fixtures.Backup.backupJson.credentials); - - expect(backup.dids).to.have.length(Fixtures.Backup.backupJson.dids.length); - expect(backup.dids).to.have.deep.members(Fixtures.Backup.backupJson.dids); - - expect(backup.did_pairs).to.have.length(Fixtures.Backup.backupJson.did_pairs.length); - expect(backup.did_pairs).to.have.deep.members(Fixtures.Backup.backupJson.did_pairs); - - expect(backup.keys).to.have.length(Fixtures.Backup.backupJson.keys.length); - expect(backup.keys).to.have.deep.members(Fixtures.Backup.backupJson.keys); - - expect(backup.messages).to.have.length(Fixtures.Backup.backupJson.messages.length); - expect(backup.messages).to.have.deep.members(Fixtures.Backup.backupJson.messages); - - expect(backup.link_secret).to.eq(Fixtures.Backup.backupJson.link_secret); + + describe(`Round trip ${version}`, () => { + test("Restore -> Backup", async () => { + await instance.restore(Fixtures.Backup.backupJson); + + const backup = await instance.backup(version); + + expect(backup.credentials).to.have.length(Fixtures.Backup.backupJson.credentials.length); + expect(backup.credentials).to.have.deep.members(Fixtures.Backup.backupJson.credentials); + + expect(backup.dids).to.have.length(Fixtures.Backup.backupJson.dids.length); + expect(backup.dids).to.have.deep.members(Fixtures.Backup.backupJson.dids); + + expect(backup.did_pairs).to.have.length(Fixtures.Backup.backupJson.did_pairs.length); + expect(backup.did_pairs).to.have.deep.members(Fixtures.Backup.backupJson.did_pairs); + + expect(backup.keys).to.have.length(Fixtures.Backup.backupJson.keys.length); + expect(backup.keys).to.have.deep.members(Fixtures.Backup.backupJson.keys); + + if (backup.version == "0.0.1" && Fixtures.Backup.backupJson.version == "0.0.1") { + expect(backup.messages).to.have.length(Fixtures.Backup.backupJson.messages.length); + expect(backup.messages).to.have.deep.members(Fixtures.Backup.backupJson.messages); + expect(backup.link_secret).to.eq(Fixtures.Backup.backupJson.link_secret); + } + + }); + + test("Backup -> Restore", async () => { + await instance.storeCredential(Fixtures.Backup.credentialJWT); + await instance.storeCredential(Fixtures.Backup.credentialAnoncreds); + await instance.storeDIDPair(Fixtures.Backup.hostDID, Fixtures.Backup.targetDID, Fixtures.Backup.pairAlias); + await instance.storeDID(Fixtures.Backup.hostDID, Fixtures.Backup.peerDIDKeys); + if (Fixtures.Backup.backupJson.version == "0.0.1") { + await instance.storeLinkSecret(Fixtures.Backup.linkSecret); + await instance.storeMessage(Fixtures.Backup.message); + await instance.storeMediator(Fixtures.Backup.mediator); + } + + const backup = await instance.backup(version); + + expect(backup).not.to.be.null; + + const sut = mockPluto(); + await sut.start(); + await sut.restore(backup); + + const credentials = await sut.getAllCredentials(); + const dids = await sut.getAllPeerDIDs(); + const didPairs = await sut.getAllDidPairs(); + const keys = await sut.getDIDPrivateKeysByDID(Fixtures.Backup.hostDID); + const mediators = await sut.getAllMediators(); + const messages = await sut.getAllMessages(); + const linksecret = await sut.getLinkSecret(); + + expect(dids).not.to.be.null; + + expect(credentials).to.have.length(2); + // expect(credentials.map(x => (x as any).toStorable())).to.have.deep.members([Fixtures.Backup.credentialAnoncreds.toStorable(), Fixtures.Backup.credentialJWT.toStorable()]); + + expect(dids).to.have.length(2); + expect(didPairs).to.have.length(1); + expect(keys).to.have.length(1); + if (version == "0.0.1") { + expect(mediators).to.have.length(1); + expect(messages).to.have.length(1); + expect(linksecret).to.have.length(1); + } + + }); }); - test("Backup -> Restore", async () => { - await instance.storeCredential(Fixtures.Backup.credentialJWT); - await instance.storeCredential(Fixtures.Backup.credentialAnoncreds); - await instance.storeDIDPair(Fixtures.Backup.hostDID, Fixtures.Backup.targetDID, Fixtures.Backup.pairAlias); - await instance.storeDID(Fixtures.Backup.hostDID, Fixtures.Backup.peerDIDKeys); - await instance.storeLinkSecret(Fixtures.Backup.linkSecret); - await instance.storeMessage(Fixtures.Backup.message); - await instance.storeMediator(Fixtures.Backup.mediator); - - const backup = await instance.backup(); - - expect(backup).not.to.be.null; - - const sut = mockPluto(); - await sut.start(); - await sut.restore(backup); - - const credentials = await sut.getAllCredentials(); - const dids = await sut.getAllPeerDIDs(); - const didPairs = await sut.getAllDidPairs(); - const keys = await sut.getDIDPrivateKeysByDID(Fixtures.Backup.hostDID); - const mediators = await sut.getAllMediators(); - const messages = await sut.getAllMessages(); - const linksecret = await sut.getLinkSecret(); - - expect(dids).not.to.be.null; - - expect(credentials).to.have.length(2); - // expect(credentials.map(x => (x as any).toStorable())).to.have.deep.members([Fixtures.Backup.credentialAnoncreds.toStorable(), Fixtures.Backup.credentialJWT.toStorable()]); - - expect(dids).to.have.length(2); - expect(didPairs).to.have.length(1); - expect(keys).to.have.length(1); - expect(mediators).to.have.length(1); - expect(messages).to.have.length(1); - - }); }); + });