diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e3fed1da..458be1a2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -57,7 +57,7 @@ jobs: strategy: matrix: os: ['ubuntu-latest'] - keria-version: ['0.2.0-dev5'] + keria-version: ['0.2.0-dev6'] node-version: ['20'] env: KERIA_IMAGE_TAG: ${{ matrix.keria-version }} diff --git a/docker-compose.yaml b/docker-compose.yaml index 1900fea1..2c640091 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -21,13 +21,13 @@ services: - 7723:7723 keria: - image: ${KERIA_IMAGE:-weboftrust/keria}:${KERIA_IMAGE_TAG:-0.2.0-dev5} + image: ${KERIA_IMAGE:-weboftrust/keria}:${KERIA_IMAGE_TAG:-0.2.0-dev6} environment: KERI_AGENT_CORS: 1 <<: *python-env volumes: - ./config/keria.json:/keria/config/keri/cf/keria.json - command: --config-dir /keria/config --config-file keria --name agent + command: start --config-dir /keria/config --config-file keria --name agent healthcheck: test: wget --spider http://keria:3902/spec.yaml <<: *healthcheck diff --git a/examples/integration-scripts/credentials.test.ts b/examples/integration-scripts/credentials.test.ts index e9dc4174..54ae22c5 100644 --- a/examples/integration-scripts/credentials.test.ts +++ b/examples/integration-scripts/credentials.test.ts @@ -616,4 +616,18 @@ test('single signature credentials', async () => { assert.equal(issuerCredential.status.s, '1'); }); + + await step('Holder deletes LE credential', async () => { + await holderClient.credentials().delete(leCredentialId); + await assert.rejects( + async () => { + await holderClient.credentials().get(leCredentialId); + }, + { + name: 'Error', + message: `HTTP GET /credentials/${leCredentialId} - 404 Not Found - {"title": "404 Not Found", "description": "credential for said ${leCredentialId} not found."}`, + } + ); + assert.equal((await holderClient.credentials().list()).length, 1); + }); }, 90000); diff --git a/src/keri/app/contacting.ts b/src/keri/app/contacting.ts index 29b4888e..9dca4fb5 100644 --- a/src/keri/app/contacting.ts +++ b/src/keri/app/contacting.ts @@ -92,7 +92,7 @@ export class Contacts { const path = `/contacts/` + pre; const method = 'DELETE'; - await this.client.fetch(path, method, null); + await this.client.fetch(path, method, undefined); } /** diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index a48928c2..53e2a51a 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -305,6 +305,18 @@ export class Credentials { return includeCESR ? await res.text() : await res.json(); } + /** + * Delete a credential from the DB + * @async + * @param {string} said - SAID of the credential + * @returns {Promise} + */ + async delete(said: string): Promise { + const path = `/credentials/${said}`; + const method = 'DELETE'; + await this.client.fetch(path, method, undefined); + } + /** * Get the state of a credential * @async diff --git a/src/keri/app/notifying.ts b/src/keri/app/notifying.ts index 17de435b..6b005b7c 100644 --- a/src/keri/app/notifying.ts +++ b/src/keri/app/notifying.ts @@ -59,11 +59,11 @@ export class Notifications { * Delete a notification * @async * @param {string} said SAID of the notification - * @returns {Promise} A promise to the result of the deletion + * @returns {Promise} */ async delete(said: string): Promise { const path = `/notifications/` + said; const method = 'DELETE'; - await this.client.fetch(path, method, null); + await this.client.fetch(path, method, undefined); } } diff --git a/src/keri/core/state.ts b/src/keri/core/state.ts index ea908378..14ae6047 100644 --- a/src/keri/core/state.ts +++ b/src/keri/core/state.ts @@ -61,6 +61,7 @@ export interface HabState { transferable: boolean; state: State; windexes: unknown[]; + icp_dt: string; [Algos.salty]?: SaltyState; [Algos.randy]?: RandyState; [Algos.group]?: GroupState; diff --git a/test/app/clienting.test.ts b/test/app/clienting.test.ts index c1c93c69..cd8a8f06 100644 --- a/test/app/clienting.test.ts +++ b/test/app/clienting.test.ts @@ -303,7 +303,9 @@ describe('SignifyClient', () => { headers: badAgentHeaders, }); let t = async () => await client.fetch('/contacts', 'GET', undefined); - expect(t).rejects.toThrowError('message from a different remote agent'); + await expect(t).rejects.toThrowError( + 'message from a different remote agent' + ); badAgentHeaders = { 'signify-resource': 'EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei', @@ -319,7 +321,7 @@ describe('SignifyClient', () => { headers: badAgentHeaders, }); t = async () => await client.fetch('/contacts', 'GET', undefined); - expect(t).rejects.toThrowError( + await expect(t).rejects.toThrowError( 'Signature for EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei invalid.' ); diff --git a/test/app/contacting.test.ts b/test/app/contacting.test.ts index 5be1753d..858d6e79 100644 --- a/test/app/contacting.test.ts +++ b/test/app/contacting.test.ts @@ -175,12 +175,12 @@ describe('Contacting', () => { await contacts.delete('EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao'); lastCall = fetchMock.mock.calls[fetchMock.mock.calls.length - 1]!; - lastBody = JSON.parse(lastCall[1]!.body!.toString()); assert.equal( lastCall[0]!, url + '/contacts/EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao' ); assert.equal(lastCall[1]!.method, 'DELETE'); + assert.equal(lastCall[1]!.body, undefined); }); it('Challenges', async () => { diff --git a/test/app/credentialing.test.ts b/test/app/credentialing.test.ts index a293a36a..1cd5bea3 100644 --- a/test/app/credentialing.test.ts +++ b/test/app/credentialing.test.ts @@ -325,6 +325,15 @@ describe('Credentialing', () => { ); assert.equal(lastCall[1]!.method, 'GET'); assert.equal(lastCall[1]!.body, null); + + await credentials.delete(mockCredential.sad.d); + lastCall = fetchMock.mock.calls[fetchMock.mock.calls.length - 1]!; + assert.equal( + lastCall[0]!, + url + '/credentials/EMwcsEMUEruPXVwPCW7zmqmN8m0I3CihxolBm-RDrsJo' + ); + assert.equal(lastCall[1]!.method, 'DELETE'); + assert.equal(lastCall[1]!.body, undefined); }); }); diff --git a/test/app/registry.test.ts b/test/app/registry.test.ts index 3e72355b..255554cf 100644 --- a/test/app/registry.test.ts +++ b/test/app/registry.test.ts @@ -70,6 +70,7 @@ describe('registry', () => { name: 'a name', transferable: true, windexes: [], + icp_dt: '2023-12-01T10:05:25.062609+00:00', } as HabState; when(mockedIdentifiers.get('a name')).thenResolve(hab); @@ -79,7 +80,7 @@ describe('registry', () => { const registries = new Registries(instance(mockedClient)); - assert.rejects( + await assert.rejects( async () => { await registries.create({ name: 'a name', diff --git a/test/app/test-utils.ts b/test/app/test-utils.ts index 8d233b09..668ad8ad 100644 --- a/test/app/test-utils.ts +++ b/test/app/test-utils.ts @@ -111,5 +111,6 @@ export async function createMockIdentifierState( c: [], di: serder.ked.di ?? '', } as State, + icp_dt: '2023-12-01T10:05:25.062609+00:00', }; } diff --git a/test/core/manager.test.ts b/test/core/manager.test.ts index 47e43ad6..6f4a3d0c 100644 --- a/test/core/manager.test.ts +++ b/test/core/manager.test.ts @@ -722,6 +722,7 @@ describe('Manager', () => { randy: keeper0.params() as RandyState, transferable: false, windexes: [], + icp_dt: '2023-12-01T10:05:25.062609+00:00', }); assert(keeper0 instanceof RandyKeeper); @@ -744,6 +745,7 @@ describe('Manager', () => { state: {} as State, transferable: false, windexes: [], + icp_dt: '2023-12-01T10:05:25.062609+00:00', }) ).toThrow('Algo not allowed yet'); }); @@ -821,6 +823,7 @@ describe('Manager', () => { param, }, transferable: true, + icp_dt: '2023-12-01T10:05:25.062609+00:00', }); assert(keeper instanceof MockModule); @@ -847,6 +850,7 @@ describe('Manager', () => { param, }, transferable: true, + icp_dt: '2023-12-01T10:05:25.062609+00:00', }) ).toThrow('unsupported external module type mock'); });