From 67f34aaccc5ca1095b96c93f2386760aeb03821f Mon Sep 17 00:00:00 2001 From: bnonni Date: Tue, 27 Aug 2024 19:57:10 -0400 Subject: [PATCH] Refactor/redundant config options (#120) * combine options into config and use unshift to push .use() options to front of list * fix lint * Refactor redundant config and options #118 * Updated @dcx-protocol/root to version 2.0.0 Updated @dcx-protocol/applicant to version 2.0.0 Updated @dcx-protocol/common to version 3.0.0 Updated @dcx-protocol/issuer to version 2.0.0 Updated @dcx-protocol/server to version 2.0.0 Package versions updated: { root: '2.0.0', applicant: '2.0.0', common: '3.0.0', issuer: '2.0.0', server: '2.0.0' } * add changeset for major version bump * fix build and tests * remove close() * bump common minor --- .changeset/fair-candles-clean.md | 5 + package.json | 2 +- .../applicant/tests/dcx-applicant.spec.ts | 4 +- packages/common/package.json | 2 +- packages/common/src/dcx-config.ts | 15 +- packages/common/src/dcx-identity-vault.ts | 31 +- packages/common/tests/dcx-agent.spec.ts | 57 +-- packages/common/tests/dcx-config.spec.ts | 5 +- .../common/tests/dcx-identity-vault.spec.ts | 150 ++++--- packages/issuer/tests/dcx-issuer.spec.ts | 5 +- packages/server/tests/dcx-server.spec.ts | 371 ++++++++---------- 11 files changed, 337 insertions(+), 310 deletions(-) create mode 100644 .changeset/fair-candles-clean.md diff --git a/.changeset/fair-candles-clean.md b/.changeset/fair-candles-clean.md new file mode 100644 index 00000000..4b030403 --- /dev/null +++ b/.changeset/fair-candles-clean.md @@ -0,0 +1,5 @@ +--- +'@dcx-protocol/common': minor +--- + +slightly changes the dcx-config related to #118 diff --git a/package.json b/package.json index 1b363641..43671216 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dcx-protocol/root", - "version": "2.0.0", + "version": "3.1.0", "description": "DCX: Decentralized Credential Exchange. DWN protocol for verifiable credential exchange.", "type": "module", "workspaces": [ diff --git a/packages/applicant/tests/dcx-applicant.spec.ts b/packages/applicant/tests/dcx-applicant.spec.ts index 13d6da6a..2a8270fe 100644 --- a/packages/applicant/tests/dcx-applicant.spec.ts +++ b/packages/applicant/tests/dcx-applicant.spec.ts @@ -51,12 +51,12 @@ describe('applicant = new DcxApplicant({ config: applicantConfig })', () => { describe('applicant.config', () => { // Check applicant.config property "web5Password" it('should contain property "web5Password" as a string', () => { - expect(applicant.config.web5Password).to.be.a('boolean').and.to.be.false; + expect(applicant.config.web5Password).to.be.a('string'); }); // Check applicant.config property "web5RecoveryPhrase" it('should contain property "web5RecoveryPhrase" as a string', () => { - expect(applicant.config.web5RecoveryPhrase).to.be.a('boolean').and.to.be.false; + expect(applicant.config.web5RecoveryPhrase).to.be.a('string'); }); // Check applicant.config property "handlers" diff --git a/packages/common/package.json b/packages/common/package.json index cd38272e..2cf3980a 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,6 +1,6 @@ { "name": "@dcx-protocol/common", - "version": "3.0.0", + "version": "3.1.0", "description": "Common library shared by the other @dcx-protocol packages", "type": "module", "main": "./dist/cjs/index.js", diff --git a/packages/common/src/dcx-config.ts b/packages/common/src/dcx-config.ts index 0a3822d4..4ce8960b 100644 --- a/packages/common/src/dcx-config.ts +++ b/packages/common/src/dcx-config.ts @@ -8,7 +8,7 @@ import { TrustedIssuer } from './index.js'; -export interface IDcxConfig { +export type DcxConfig = { handlers: Handler[]; providers: Provider[]; manifests: CredentialManifest[]; @@ -17,15 +17,6 @@ export interface IDcxConfig { dwns: string[]; } -export class DcxConfig implements IDcxConfig { - handlers: Handler[] = []; - providers: Provider[] = []; - manifests: CredentialManifest[] = []; - issuers: TrustedIssuer[] = []; - gateways: string[] = []; - dwns: string[] = []; -} - export const MX = { name: 'mx', id: 'did:dht:kfcakjzahwimgo9zzjw6yknt9srdtkmfqbeybekcg3xzz1ztg95y' }; export const FF = { name: 'formfree', id: 'did:dht:hcf5e55bbm44s4oixp5z89wtxenxyk35su7f5pd4r5np93ikyowy' }; @@ -34,6 +25,6 @@ export const dcxConfig: DcxConfig = { providers : [], manifests : [DcxHandshakeManifest, PhoneNumberManifest, EmailAddressManifest], issuers : [MX, FF], - gateways : ['https://dwn.tbddev.org/beta'], - dwns : ['https://diddht.tbddev.org/'], + gateways : ['https://diddht.tbddev.org/'], + dwns : ['https://dwn.tbddev.org/beta'], }; \ No newline at end of file diff --git a/packages/common/src/dcx-identity-vault.ts b/packages/common/src/dcx-identity-vault.ts index dedf7585..b920c9d8 100644 --- a/packages/common/src/dcx-identity-vault.ts +++ b/packages/common/src/dcx-identity-vault.ts @@ -272,8 +272,35 @@ export class DcxIdentityVault implements IdentityVault<{ InitializeResult: strin } } - async backup(): Promise { - throw new Error('Method not implemented.'); + public async backup(): Promise { + // Verify the identity vault has already been initialized and unlocked. + if (this.isLocked() || await this.isInitialized() === false) { + throw new Error( + 'HdIdentityVault: Unable to proceed with the backup operation because the identity vault ' + + 'has not been initialized and unlocked. Please ensure the vault is properly initialized ' + + 'with a secure password before attempting to backup its contents.' + ); + } + + // Encode the encrypted CEK and DID as a single Base64Url string. + const backupData: IdentityVaultBackupData = { + did : await this.getStoredDidDcx(), + contentEncryptionKey : await this.getStoredContentEncryptionKeyDcx(), + status : await this.getStatus() + }; + const backupDataString = Convert.object(backupData).toBase64Url(); + + // Create a backup object containing the encrypted vault contents. + const backup: IdentityVaultBackup = { + data : backupDataString, + dateCreated : new Date().toISOString(), + size : backupDataString.length + }; + + // Update the last backup timestamp in the data store. + await this.setStatusDcx({ lastBackup: backup.dateCreated }); + + return backup; } public async initialize({ diff --git a/packages/common/tests/dcx-agent.spec.ts b/packages/common/tests/dcx-agent.spec.ts index f18765dc..7a1b8361 100644 --- a/packages/common/tests/dcx-agent.spec.ts +++ b/packages/common/tests/dcx-agent.spec.ts @@ -3,21 +3,24 @@ import { expect } from 'chai'; import { DcxAgent, DcxIdentityVault, FileSystem, Mnemonic } from '../src/index.js'; import { LevelStore } from '@web5/common'; -describe('DcxAgent', () => { - const dataPath = '__TEST_DATA__/DCX/COMMON/AGENT'; +describe('agent = await DcxAgent.create({ dataPath, agentVault: new DcxIdentityVault({ location }) })', () => { + const dataPath = '__AGENT_DATA__/DCX/COMMON/AGENT'; const password = Mnemonic.createPassword(); const recoveryPhrase = Mnemonic.createRecoveryPhrase(); - const location = `${dataPath}/VAULT_STORE`; let agent: DcxAgent; + before(async () => { + agent = await DcxAgent.create({ dataPath }); + }); + after(async () => { - await FileSystem.rm('__TEST_DATA__', { recursive: true, force: true }); + await agent.vault.store.close(); + await FileSystem.rm('__AGENT_DATA__', { recursive: true, force: true }); }); - describe('agent = await DcxAgent.create({ dataPath, agentVault: new DcxIdentityVault({ location }) })', () => { + describe('agent', () => { it('should be an instanceof DcxAgent', async () => { - agent = await DcxAgent.create({ dataPath, agentVault: new DcxIdentityVault({ location }) }); expect(agent).to.be.instanceof(DcxAgent); }); @@ -38,35 +41,35 @@ describe('DcxAgent', () => { expect(agent.vault.store).to.be.instanceof(LevelStore); }); }); - }); - describe('await agent.firstLaunch()', () => { - it('should be true', async () => { - expect(await agent.firstLaunch()).to.be.true; + describe('await agent.firstLaunch()', () => { + it('should be true', async () => { + expect(await agent.firstLaunch()).to.be.true; + }); }); - }); - describe('await agent.initialize({ password, recoveryPhrase, dwnEndpoints })', () => { - it('should initialize and return a matching recoveryPhrase', async () => { - expect(await agent.initialize({ password, recoveryPhrase, dwnEndpoints: ['http://localhost:3000'] })).to.equal(recoveryPhrase); - }); + describe('await agent.initialize({ password, recoveryPhrase, dwnEndpoints })', () => { + it('should initialize and return a matching recoveryPhrase', async () => { + expect(await agent.initialize({ password, recoveryPhrase, dwnEndpoints: ['http://localhost:3000'] })).to.equal(recoveryPhrase); + }); - it('should have a vault that is initialized', async () => { - expect(await agent.vault.isInitialized()).to.be.true; + it('should have a vault that is initialized', async () => { + expect(await agent.firstLaunch()).to.be.false; + }); }); - }); - describe('await agent.start({ password })', () => { - it('should start the agent', async () => { - await agent.start({ password }); - }); + describe('await agent.start({ password })', () => { + it('should start the agent', async () => { + await agent.start({ password }); + }); - it('should have an unlocked vault', () => { - expect(agent.vault.isLocked()).to.be.false; - }); + it('should have an unlocked vault', () => { + expect(agent.vault.isLocked()).to.be.false; + }); - it('should have agentDid as instanceof BearerDid', () => { - expect(agent.agentDid).to.be.instanceof(BearerDid); + it('should have agentDid as instanceof BearerDid', () => { + expect(agent.agentDid).to.be.instanceof(BearerDid); + }); }); }); }); \ No newline at end of file diff --git a/packages/common/tests/dcx-config.spec.ts b/packages/common/tests/dcx-config.spec.ts index c6ba5f87..4d324973 100644 --- a/packages/common/tests/dcx-config.spec.ts +++ b/packages/common/tests/dcx-config.spec.ts @@ -2,12 +2,9 @@ import dotenv from 'dotenv'; dotenv.config({ path: '.env.test' }); import { expect } from 'chai'; -import { DcxConfig, dcxConfig } from '../src/index.js'; +import { dcxConfig } from '../src/index.js'; describe('DcxConfig', () => { - it('should be an instance of DcxConfig', () => { - expect(dcxConfig).that.is.an.instanceof(DcxConfig); - }); it('should have entries of length >= 6', () => { expect(Object.entries(dcxConfig)).to.have.lengthOf.gte(6); diff --git a/packages/common/tests/dcx-identity-vault.spec.ts b/packages/common/tests/dcx-identity-vault.spec.ts index 4c4a9b8e..e56e2dc8 100644 --- a/packages/common/tests/dcx-identity-vault.spec.ts +++ b/packages/common/tests/dcx-identity-vault.spec.ts @@ -1,27 +1,30 @@ import { expect } from 'chai'; import { DcxIdentityVault, Mnemonic, FileSystem } from '../src/index.js'; import { LevelStore, MemoryStore } from '@web5/common'; - -type DxcxIdentityVaultStatus = { initialized: boolean; lastBackup: string | null; lastRestore: string | null }; +import { IdentityVaultBackup } from '@web5/agent'; process.env.NODE_ENV = 'test'; describe('DcxIdentityVault', () => { - const location = '__TEST_DATA__/DCX/COMMON/AGENT/VAULT_STORE'; const dwnEndpoints = ['http://localhost:3000']; - let recoveryPhrase = Mnemonic.createRecoveryPhrase(); - let password = Mnemonic.createPassword(); - let vaultStatus: DxcxIdentityVaultStatus; - let returnedRecoveryPhrase: string; + const location = '__VAULT_DATA__/DCX/COMMON/AGENT/VAULT_STORE'; + let vault: DcxIdentityVault; + let backup: IdentityVaultBackup; - afterEach(async () => { - await FileSystem.rm('__TEST_DATA__', { recursive: true, force: true }); + after(async () => { + await vault.store.close(); + await FileSystem.rm('__VAULT_DATA__', { recursive: true, force: true }); }); describe(`agentVault = new DcxIdentityVault({ location: ${location} })`, () => { - recoveryPhrase = Mnemonic.createRecoveryPhrase(); - password = Mnemonic.createPassword(); - const agentVault = new DcxIdentityVault({ location }); + const agentVault = vault = new DcxIdentityVault({ location }); + + const password = Mnemonic.createPassword(); + const recoveryPhrase = Mnemonic.createRecoveryPhrase(); + + after(async () => { + await agentVault.store.close(); + }); it('should be instanceof DcxIdentityVault', () => { expect(agentVault).to.be.instanceof(DcxIdentityVault); @@ -35,41 +38,55 @@ describe('DcxIdentityVault', () => { expect(agentVault).to.have.property('keyDerivationWorkFactor').that.is.a('number').and.equals(210_000); }); - describe('await agentVault.getStatus()', () => { - it('should have status of initialized=false lastBackup=null lastRestore=null', async () => { - vaultStatus = await agentVault.getStatus(); - expect(vaultStatus.initialized).to.be.false; - expect(vaultStatus.lastBackup).to.be.null; - expect(vaultStatus.lastRestore).to.be.null; - }); + it('should have status of initialized=false lastBackup=null lastRestore=null', async () => { + const vaultStatus = await agentVault.getStatus(); + expect(vaultStatus.initialized).to.be.false; + expect(vaultStatus.lastBackup).to.be.null; + expect(vaultStatus.lastRestore).to.be.null; }); - describe('await agentVault.initialize({ password, recoveryPhrase, dwnEndpoints })', () => { - it('should initialize successfully', async () => { - returnedRecoveryPhrase = await agentVault.initialize({ password, recoveryPhrase, dwnEndpoints }); - }); + it('initialize(): should successfully initialize the agentVault', async () => { + const initialize = await agentVault.initialize({ password, recoveryPhrase, dwnEndpoints }); + expect(initialize).to.equal(recoveryPhrase); + }); - it('should return a matching recoveryPhrase', async () => { - expect(returnedRecoveryPhrase).to.equal(recoveryPhrase); - }); + it('should have property "contentEncryptionKey" after initialization', () => { + expect(agentVault).to.have.property('contentEncryptionKey'); + }); - it('should have property "contentEncryptionKey" after initialization', async () => { - expect(agentVault).to.have.property('contentEncryptionKey'); - }); + it('getStatus(): should have a new status of initialized=true lastBackup=null lastRestore=null', async () => { + const vaultStatus = await agentVault.getStatus(); + expect(vaultStatus.initialized).to.be.true; + expect(vaultStatus.lastBackup).to.be.null; + expect(vaultStatus.lastRestore).to.be.null; + }); + + it('backup(): should backup the agentVault', async () => { + backup = await agentVault.backup(); + }); + + it('lock(): should lock the agentVault', async () => { + await agentVault.lock(); + }); + + it('unlock(): should unlock the agentVault', async () => { + await agentVault.unlock({ password }); + }); - it('should have updated status of initialized=true lastBackup=null lastRestore=null', async () => { - vaultStatus = await agentVault.getStatus(); - expect(vaultStatus.initialized).to.be.true; - expect(vaultStatus.lastBackup).to.be.null; - expect(vaultStatus.lastRestore).to.be.null; - }); + it('restore(): should restore the agentVault', async () => { + await agentVault.restore({ password, backup }); }); }); - describe(`memoryVault = new DcxIdentityVault({ store: new MemoryStore(), location: ${location} })`, () => { - recoveryPhrase = Mnemonic.createRecoveryPhrase(); - password = Mnemonic.createPassword(); - const memoryVault = new DcxIdentityVault({ store: new MemoryStore(), location }); + + describe(`memoryVault = new DcxIdentityVault({ store: new MemoryStore() })`, () => { + const memoryVault = vault = new DcxIdentityVault({ store: new MemoryStore() }); + const password = Mnemonic.createPassword(); + const recoveryPhrase = Mnemonic.createRecoveryPhrase(); + + after(async () => { + await memoryVault.store.close(); + }); it('should be instanceof DcxIdentityVault', () => { expect(memoryVault).to.be.instanceof(DcxIdentityVault); @@ -83,34 +100,43 @@ describe('DcxIdentityVault', () => { expect(memoryVault).to.have.property('keyDerivationWorkFactor').that.is.a('number').and.equals(210_000); }); - describe('await memoryVault.getStatus()', () => { - it('should have status of initialized=false lastBackup=null lastRestore=null', async () => { - vaultStatus = await memoryVault.getStatus(); - expect(vaultStatus.initialized).to.be.false; - expect(vaultStatus.lastBackup).to.be.null; - expect(vaultStatus.lastRestore).to.be.null; - }); + it('should have status of initialized=false lastBackup=null lastRestore=null', async () => { + const vaultStatus = await memoryVault.getStatus(); + expect(vaultStatus.initialized).to.be.false; + expect(vaultStatus.lastBackup).to.be.null; + expect(vaultStatus.lastRestore).to.be.null; + }); + + it('should initialize the memoryVault and return a matching recovery phrase', async () => { + const initialize = await memoryVault.initialize({ password, recoveryPhrase, dwnEndpoints }); + expect(initialize).to.equal(recoveryPhrase); + }); + + it('should have property "contentEncryptionKey" after initialization', () => { + expect(memoryVault).to.have.property('contentEncryptionKey'); + }); + + it('should have a new status of initialized=true lastBackup=null lastRestore=null', async () => { + const vaultStatus = await memoryVault.getStatus(); + expect(vaultStatus.initialized).to.be.true; + expect(vaultStatus.lastBackup).to.be.null; + expect(vaultStatus.lastRestore).to.be.null; }); - describe('await memoryVault.initialize({ password, recoveryPhrase, dwnEndpoints })', () => { - it('should initialize successfully with params { password, recoveryPhrase, dwnEndpoints }', async () => { - returnedRecoveryPhrase = await memoryVault.initialize({ password, recoveryPhrase, dwnEndpoints }); - }); + it('should backup the memoryVault', async () => { + backup = await memoryVault.backup(); + }); - it('should return a matching recoveryPhrase', () => { - expect(recoveryPhrase).to.equal(returnedRecoveryPhrase); - }); + it('should lock the memoryVault', async () => { + await memoryVault.lock(); + }); - it('should have property "contentEncryptionKey" after initialization', () => { - expect(memoryVault).to.have.property('contentEncryptionKey'); - }); + it('should unlock the memoryVault', async () => { + await memoryVault.unlock({ password }); + }); - it('should have updated status of initialized=true lastBackup=null lastRestore=null', async () => { - vaultStatus = await memoryVault.getStatus(); - expect(vaultStatus.initialized).to.be.true; - expect(vaultStatus.lastBackup).to.be.null; - expect(vaultStatus.lastRestore).to.be.null; - }); + it('should restore the memoryVault', async () => { + await memoryVault.restore({ password, backup }); }); }); }); \ No newline at end of file diff --git a/packages/issuer/tests/dcx-issuer.spec.ts b/packages/issuer/tests/dcx-issuer.spec.ts index f79d31a2..1989661d 100644 --- a/packages/issuer/tests/dcx-issuer.spec.ts +++ b/packages/issuer/tests/dcx-issuer.spec.ts @@ -6,6 +6,7 @@ import { DcxIssuer, issuerConfig } from '../src/index.js'; process.env.NODE_ENV = 'test'; describe('issuer = new DcxIssuer({ ... })', () => { + issuerConfig.dwns = ['http://localhost:3000']; issuerConfig.agentDataPath = '__TEST_DATA__/DCX/ISSUER/AGENT'; const issuer: DcxIssuer = new DcxIssuer({ config: issuerConfig }); @@ -59,12 +60,12 @@ describe('issuer = new DcxIssuer({ ... })', () => { // Check issuer.config property "web5Password" it('should contain property "web5Password" as a string', () => { - expect(issuer.config.web5Password).to.be.a('boolean').and.to.be.false; + expect(issuer.config.web5Password).to.be.a('string'); }); // Check issuer.config property "web5RecoveryPhrase" it('should contain property "web5RecoveryPhrase" as a string', () => { - expect(issuer.config.web5RecoveryPhrase).to.be.a('boolean').and.to.be.false; + expect(issuer.config.web5RecoveryPhrase).to.be.a('string'); }); // Check issuer.config property "handlers" diff --git a/packages/server/tests/dcx-server.spec.ts b/packages/server/tests/dcx-server.spec.ts index 79a14554..525aa1ef 100644 --- a/packages/server/tests/dcx-server.spec.ts +++ b/packages/server/tests/dcx-server.spec.ts @@ -1,6 +1,6 @@ import { DcxApplicant } from '@dcx-protocol/applicant'; -import { DcxAgent, DcxIdentityVault, DcxServerError, FileSystem, Mnemonic } from '@dcx-protocol/common'; -import { DcxIssuer } from '@dcx-protocol/issuer'; +import { DcxAgent, DcxIdentityVault, DcxServerError, FileSystem } from '@dcx-protocol/common'; +import { DcxIssuer, issuerConfig } from '@dcx-protocol/issuer'; import { Web5 } from '@web5/api'; import { expect } from 'chai'; import { ApplicantServer } from '../src/applicant-server.js'; @@ -10,7 +10,7 @@ import { IssuerServer } from '../src/issuer-server.js'; process.env.NODE_ENV = 'test'; /** - * DcxServer tests + * @class DcxServer * {@link DcxServer} * {@link DcxIssuer} * {@link IssuerServer} @@ -18,141 +18,128 @@ process.env.NODE_ENV = 'test'; * {@link ApplicantServer} */ describe('DcxServer', () => { - afterEach(async () => { + after(async () => { await FileSystem.rm('__TEST_DATA__'); + await FileSystem.rm('DATA'); }); it('should throw an error with empty constructor: new DcxServer() ', () => { expect(() => new DcxServer()).to.throw(DcxServerError); }); - describe('with { type: "issuer" }', () => { + /** + * new DcxServer({ type: "issuer" }) + * @param {ServerParams} params.type = "issuer" + */ + describe('server = new DcxServer({ type: "issuer" })', () => { const server = new DcxServer({ type: 'issuer' }); - const issuerServer = server.issuerServer; - const issuer = server.issuer; - const listening = server.listening; - const testing = server.testing; - - describe('server = new DcxServer({ type: "issuer" })', () => { - it('should be defined as an instanceof DcxServer', () => { - expect(server).be.instanceof(DcxServer); - }); - it('should contain property server.issuerServer as an instanceof IssuerServer', () => { - expect(issuerServer).be.instanceof(IssuerServer); - }); + it('should be defined as an instanceof DcxServer', () => { + expect(server).be.instanceof(DcxServer); + }); - it('should contain property server.issuer as an instance of DcxIssuer', () => { - expect(issuer).to.be.instanceof(DcxIssuer); - }); + it('should contain property server.issuerServer as an instanceof IssuerServer', () => { + expect(server.issuerServer).be.instanceof(IssuerServer); + }); - it('should throw DcxServerError when trying to access server.applicantServer', () => { - expect(() => server.applicantServer).to.throw(DcxServerError); - }); + it('should contain property server.issuer as an instance of DcxIssuer', () => { + expect(server.issuer).to.be.instanceof(DcxIssuer); + }); - it('should throw DcxServerError when trying to access server.applicant', () => { - expect(() => server.applicant).to.throw(DcxServerError); - }); + it('should throw DcxServerError when trying to access server.applicantServer', () => { + expect(() => server.applicantServer).to.throw(DcxServerError); + }); - it('should contain property server.listening', () => { - expect(listening).to.be.a('boolean').and.to.be.false; - }); + it('should throw DcxServerError when trying to access server.applicant', () => { + expect(() => server.applicant).to.throw(DcxServerError); + }); - it('should contain property server.testing', () => { - expect(testing).to.be.a('boolean').and.to.be.true; - }); + it('should contain property server.listening', () => { + expect(server.listening).to.be.a('boolean').and.to.be.false; + }); + + it('should contain property server.testing', () => { + expect(server.testing).to.be.a('boolean').and.to.be.true; }); }); /** - * @class DcxServer - * @method constructor - * @param {ServerParams} params.type = "issuer"; see {@link ServerParams} + * new DcxServer({ type: "applicant" }) + * @param {ServerParams} params.type = "applicant" + * + * @property {DcxServer} server + * @property {ApplicantServer} server.applicantServer + * @property {DcxApplicant} server.applicant + * @property {DcxIssuer} server.issuer + * @property {IssuerServer} server.issuerServer + * @property {boolean} server.listening + * @property {boolean} server.testing */ - describe('with { type: "applicant" }', () => { - const server: DcxServer = new DcxServer({ type: 'applicant' }); - const applicantServer = server.applicantServer; - const applicant = server.applicant; - const listening = server.listening; - const testing = server.testing; + describe('server = new DcxServer({ type: "applicant" });', () => { + const server = new DcxServer({ type: 'applicant' }); - /** - * @property {DcxServer} server - * @property {ApplicantServer} server.applicantServer - * @property {DcxApplicant} server.applicant - * @property {DcxIssuer} server.issuer - * @property {IssuerServer} server.issuerServer - * @property {boolean} server.listening - * @property {boolean} server.testing - */ - describe('server = new DcxServer({ type: "applicant" })', () => { - it('should be defined as an instanceof DcxServer', () => { - expect(server).be.instanceof(DcxServer); - }); + it('should be an instanceof DcxServer', () => { + expect(server).be.instanceof(DcxServer); + }); - it('should contain property "server.applicantServer" as an instanceof ApplicantServer', () => { - expect(applicantServer).be.instanceof(ApplicantServer); - }); + it('should contain property "server.applicantServer" as an instanceof ApplicantServer', () => { + expect(server.applicantServer).be.instanceof(ApplicantServer); + }); - it('should contain property "server.applicant" as an instance of DcxApplicant', () => { - expect(applicant).to.be.instanceof(DcxApplicant); - }); + it('should contain property "server.applicant" as an instance of DcxApplicant', () => { + expect(server.applicant).to.be.instanceof(DcxApplicant); + }); - it('should throw DcxServerError when trying to access "server.issuerServer"', () => { - expect(() => server.issuerServer).to.throw(DcxServerError); - }); + it('should throw DcxServerError when trying to access "server.issuerServer"', () => { + expect(() => server.issuerServer).to.throw(DcxServerError); + }); - it('should throw DcxServerError when trying to access "server.issuer"', () => { - expect(() => server.issuer).to.throw(DcxServerError); - }); + it('should throw DcxServerError when trying to access "server.issuer"', () => { + expect(() => server.issuer).to.throw(DcxServerError); + }); - it('should contain property "server.listening"', () => { - expect(listening).to.be.a('boolean').and.to.be.false; - }); + it('should contain property "server.listening"', () => { + expect(server.listening).to.be.a('boolean').and.to.be.false; + }); - it('should contain property "server.testing"', () => { - expect(testing).to.be.a('boolean').and.to.be.true; - }); + it('should contain property "server.testing"', () => { + expect(server.testing).to.be.a('boolean').and.to.be.true; }); }); - describe('with { issuer: new DcxIssuer() }', () => { - describe('server = new DcxServer({ issuer: new DcxIssuer() })', () => { - const server: DcxServer = new DcxServer({ issuer: new DcxIssuer() }); - const issuer = server.issuer; - const config = issuer.config; - const status = issuer.status; + describe('server = new DcxServer({ issuer: new DcxIssuer({ config: issuerConfig }) })', () => { + issuerConfig.dwns = ['http://localhost:3000']; + issuerConfig.agentDataPath = '__TEST_DATA__/SERVER/DCX/ISSUER/AGENT'; - /** - * @property {IssuerServer} server.issuerServer - */ - it('should contain property "issuerServer" as an instanceof IssuerServer', () => { - expect(server.issuerServer).to.be.an.instanceof(IssuerServer); - }); + const server = new DcxServer({ issuer: new DcxIssuer({ config: issuerConfig }) }); - /** - * @property {DcxIssuer} server.issuer - */ - describe('server.issuer', () => { + it('should be an instanceof DcxServer', () => { + expect(server).be.instanceof(DcxServer); + }); - // Check server.issuer instance - it('should be an instanceof DcxIssuer', () => { - expect(issuer).to.be.an.instanceof(DcxIssuer); - }); + it('should contain property "issuerServer" as an instanceof IssuerServer', () => { + expect(server.issuerServer).to.be.an.instanceof(IssuerServer); + }); - // check server.issuer property "config" - it('should contain an object property "config"', () => { - expect(config).to.be.an('object'); - expect(Object.entries(config)).to.have.lengthOf(9); - }); + describe('server.issuer', () => { + // Check server.issuer instance + it('should be an instanceof DcxIssuer', () => { + expect(server.issuer).to.be.an.instanceof(DcxIssuer); + }); - // check server.issuer property "status" - it('should contain an object property "status"', () => { - expect(status).to.be.an('object'); - expect(Object.entries(status)).to.have.lengthOf(2); - }); + // check server.issuer property "config" + it('should contain an object property "config"', () => { + expect(server.issuer.config).to.be.an('object'); + expect(Object.entries(server.issuer.config)).to.have.lengthOf(11); + }); + + // check server.issuer property "status" + it('should contain an object property "status"', () => { + expect(server.issuer.status).to.be.an('object'); + expect(Object.entries(server.issuer.status)).to.have.lengthOf(2); + }); - /** + /** * server.issuer.config; see {@link IssuerConfig} * @property {array} server.issuer.config.handlers * @property {array} server.issuer.config.providers @@ -161,116 +148,106 @@ describe('DcxServer', () => { * @property {array} server.issuer.config.gateways * @property {array} server.issuer.config.dwns */ - describe('server.issuer.config', () => { - // Check server.issuer.options property "handlers" - it('should contain an array property "handlers" with length >= 0', () => { - expect(config).to.have.property('handlers').that.is.an('array').and.has.lengthOf.gte(0); - }); - - // Check server.issuer.options property "providers" - it('should contain an array property "providers" with length >= 0', () => { - expect(config).to.have.property('providers').that.is.an('array').and.has.lengthOf.gte(0); - }); - - // Check server.issuer.options property "manifests" - it('should contain an array property "manifests" with length >= 3', () => { - expect(config).to.have.property('manifests').that.is.an('array').and.has.lengthOf.gte(1); - }); - - // Check server.issuer.options property "issuers" - it('should contain an array property "issuers" with length >= 2', () => { - expect(config).to.have.property('issuers').that.is.an('array').and.has.lengthOf.gte(1); - }); - - // Check server.issuer.options property "gateways" - it('should contain an array property "gateways" with length >= 1', () => { - expect(config).to.have.property('gateways').that.is.an('array').and.has.lengthOf.gte(1); - }); - - // Check server.issuer.options property "dwns" - it('should contain an array property "dwns" with length >= 1', () => { - expect(config).to.have.property('dwns').that.is.an('array').and.has.lengthOf.gte(1); - }); - - // Check server.issuer.config property "cursorFile" - it('should contain string property "cursorFile"', () => { - expect(config).to.have.property('cursorFile').that.is.a('string'); - }); - - // Check server.issuer.config property "lastRecordIdFile" - it('should contain string property "lastRecordIdFile"', () => { - expect(config).to.have.property('lastRecordIdFile').that.is.a('string'); - }); - - // Check server.issuer.config property "agentDataPath" - it('should contain string property "agentDataPath"', () => { - expect(config).to.have.property('agentDataPath').that.is.a('string'); - }); - - // Check server.issuer.config property "web5Password" - it('should contain string property "web5Password"', () => { - expect(config).to.have.property('web5Password').that.is.a('string'); - }); - - // Check server.issuer.config property "web5RecoveryPhrase" - it('should contain string property "web5RecoveryPhrase"', () => { - expect(config).to.have.property('web5RecoveryPhrase').that.is.a('string'); - }); + describe('server.issuer.config', () => { + // Check server.issuer.options property "handlers" + it('should contain an array property "handlers" with length >= 0', () => { + expect(server.issuer.config).to.have.property('handlers').that.is.an('array').and.has.lengthOf.gte(0); + }); + + // Check server.issuer.options property "providers" + it('should contain an array property "providers" with length >= 0', () => { + expect(server.issuer.config).to.have.property('providers').that.is.an('array').and.has.lengthOf.gte(0); + }); + + // Check server.issuer.options property "manifests" + it('should contain an array property "manifests" with length >= 3', () => { + expect(server.issuer.config).to.have.property('manifests').that.is.an('array').and.has.lengthOf.gte(1); + }); + + // Check server.issuer.options property "issuers" + it('should contain an array property "issuers" with length >= 2', () => { + expect(server.issuer.config).to.have.property('issuers').that.is.an('array').and.has.lengthOf.gte(1); + }); + + // Check server.issuer.options property "gateways" + it('should contain an array property "gateways" with length >= 1', () => { + expect(server.issuer.config).to.have.property('gateways').that.is.an('array').and.has.lengthOf.gte(1); + }); + + // Check server.issuer.options property "dwns" + it('should contain an array property "dwns" with length >= 1', () => { + expect(server.issuer.config).to.have.property('dwns').that.is.an('array').and.has.lengthOf.gte(1); + }); + + // Check server.issuer.config property "cursorFile" + it('should contain string property "cursorFile"', () => { + expect(server.issuer.config).to.have.property('cursorFile').that.is.a('string'); + }); + + // Check server.issuer.config property "lastRecordIdFile" + it('should contain string property "lastRecordIdFile"', () => { + expect(server.issuer.config).to.have.property('lastRecordIdFile').that.is.a('string'); }); + // Check server.issuer.config property "agentDataPath" + it('should contain string property "agentDataPath"', () => { + expect(server.issuer.config).to.have.property('agentDataPath').that.is.a('string'); + }); + + // Check server.issuer.config property "web5Password" + it('should contain string property "web5Password"', () => { + expect(server.issuer.config).to.have.property('web5Password').that.is.a('string'); + }); + + // Check server.issuer.config property "web5RecoveryPhrase" + it('should contain string property "web5RecoveryPhrase"', () => { + expect(server.issuer.config).to.have.property('web5RecoveryPhrase').that.is.a('string'); + }); + }); + - /** + /** * server.issuer.status; see {@link DcxManagerStatus} * @property {boolean} server.issuer.status.setup * @property {boolean} server.issuer.status.initialized */ - describe('server.issuer.status', () => { - // Check server.issuer.status property "setup" - it('should contain a boolean property "setup" equal to false', () => { - expect(status).to.have.property('setup').that.is.a('boolean').and.equals(false); - }); - - // Check server.issuer.status property "initialized" - it('should contain a boolean property "initialized" equal to false', () => { - expect(status).to.have.property('initialized').that.is.a('boolean').and.equals(false); - }); + describe('server.issuer.status', () => { + // Check server.issuer.status property "setup" + it('should contain a boolean property "setup" equal to false', () => { + expect(server.issuer.status).to.have.property('setup').that.is.a('boolean').and.that.is.false; }); - }); - /** - * see {@link DcxIssuer.initialize()} - * @method server.issuer.initialize() - */ - describe('await server.issuer.initialize()', () => { - // Set the issuer config variables - server.issuer.config.web5Password = Mnemonic.createPassword(); - server.issuer.config.web5RecoveryPhrase = Mnemonic.createRecoveryPhrase(); - server.issuer.config.agentDataPath = '__TEST_DATA__/DCX/ISSUER/AGENT'; - - // Check the issuer initialized status post initialization - it('should initialize the DcxIssuer', async () => { - await server.issuer.initialize(); - expect(server.issuer.status.initialized).to.be.true; + // Check server.issuer.status property "initialized" + it('should contain a boolean property "initialized" equal to false', () => { + expect(server.issuer.status).to.have.property('initialized').that.is.a('boolean').and.that.is.false; }); + }); + }); - // Check the issuer web5, agent and agentVault post initialization - it('should initialize the DcxIssuer properties: web5, agent and agentVault', () => { - expect(server.issuer.web5).to.be.instanceof(Web5); - expect(server.issuer.agent).to.be.instanceof(DcxAgent); - expect(server.issuer.agentVault).to.be.instanceof(DcxIdentityVault); - }); + /** + * see {@link DcxIssuer.initialize()} + * @method server.issuer.initialize() + */ + describe('await server.issuer.initialize()', () => { + // Check the issuer initialized status post initialization + it('should initialize the DcxIssuer', async () => { + await server.issuer.initialize(); + expect(server.issuer.status.initialized).to.be.true; + expect(server.issuer.web5).to.be.instanceof(Web5); + expect(server.issuer.agent).to.be.instanceof(DcxAgent); + expect(server.issuer.agentVault).to.be.instanceof(DcxIdentityVault); }); + }); - /** + /** * see {@link DcxIssuer.setup} * @method server.issuer.setup() */ - describe('server.issuer.setup()', () => { - // Check the issuer setup status post setup - it('should setup the issuer protocol in local and remote dwn', async () => { - await server.issuer.setup(); - expect(server.issuer.status.setup).to.be.true; - }); + describe('await server.issuer.setup()', () => { + // Check the issuer setup status post setup + it('should setup the issuer protocol in local and remote dwn', async () => { + await server.issuer.setup(); + expect(server.issuer.status.setup).to.be.true; }); }); });