Skip to content

Commit

Permalink
Merge branch 'main' into okstatus-feat
Browse files Browse the repository at this point in the history
  • Loading branch information
Toheeb-Ojuolape authored Oct 22, 2024
2 parents d4ebc48 + 05e5b64 commit 47286d7
Show file tree
Hide file tree
Showing 33 changed files with 380 additions and 75 deletions.
9 changes: 0 additions & 9 deletions .changeset/brave-cameras-reply.md

This file was deleted.

9 changes: 0 additions & 9 deletions .changeset/fair-pillows-notice.md

This file was deleted.

8 changes: 0 additions & 8 deletions .changeset/itchy-mayflies-camp.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/lemon-bees-yawn.md

This file was deleted.

8 changes: 0 additions & 8 deletions .changeset/lucky-dots-clap.md

This file was deleted.

8 changes: 0 additions & 8 deletions .changeset/many-suns-think.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/nine-moose-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@web5/api": minor
---

Identity information exclusively stored using Agent's DID as a tenant
8 changes: 0 additions & 8 deletions .changeset/rude-socks-pay.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/yellow-schools-fail.md

This file was deleted.

33 changes: 33 additions & 0 deletions packages/agent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# @web5/agent

## 0.8.1

### Patch Changes

- [#961](https://github.com/TBD54566975/web5-js/pull/961) [`ca89770`](https://github.com/TBD54566975/web5-js/commit/ca89770943c538cfe62a3cfabcced483ef768e36) Thanks [@LiranCohen](https://github.com/LiranCohen)! - Fix error where `dwn-store` records were not being updated when marked as such.

## 0.8.0

### Minor Changes

- [#914](https://github.com/TBD54566975/web5-js/pull/914) [`bd1cb00`](https://github.com/TBD54566975/web5-js/commit/bd1cb00616029b0d18687b597e90d3b7c4dbeae1) Thanks [@LiranCohen](https://github.com/LiranCohen)! - Ability to Update a DID

- [#911](https://github.com/TBD54566975/web5-js/pull/911) [`c92159c`](https://github.com/TBD54566975/web5-js/commit/c92159c32a4f45aae73eb16199185af95a4b55e3) Thanks [@LiranCohen](https://github.com/LiranCohen)! - Simplify IdentityApi to be agent-focused and storing both the DID and IdentityMetadata under the agent's tenant.

### Patch Changes

- [#953](https://github.com/TBD54566975/web5-js/pull/953) [`3f39bf1`](https://github.com/TBD54566975/web5-js/commit/3f39bf1d14cf835a2959b5386a82ff7228d31e6c) Thanks [@LiranCohen](https://github.com/LiranCohen)! - Add ability to update DWN Endpoints

- [#945](https://github.com/TBD54566975/web5-js/pull/945) [`101f463`](https://github.com/TBD54566975/web5-js/commit/101f463eae4fa54383a8ffd28292755076ce50f4) Thanks [@thehenrytsai](https://github.com/thehenrytsai)! - Added parameter for app display name for dynamic rendering in the wallet during web5 connect flow

- [#958](https://github.com/TBD54566975/web5-js/pull/958) [`7072331`](https://github.com/TBD54566975/web5-js/commit/70723312d677c3f0aac960688613b45160528f90) Thanks [@LiranCohen](https://github.com/LiranCohen)! - Prevent SyncEngine from stopping completely during a sync failure, next interval will try again.

- [#954](https://github.com/TBD54566975/web5-js/pull/954) [`5120f6f`](https://github.com/TBD54566975/web5-js/commit/5120f6fd88e4883e1b8614b513f1aa826de7ce4c) Thanks [@LiranCohen](https://github.com/LiranCohen)! - Add `getProtocolRole` util

- [#910](https://github.com/TBD54566975/web5-js/pull/910) [`d3b4728`](https://github.com/TBD54566975/web5-js/commit/d3b4728fb2ad8a15fd81d6db1865bd7b8c762561) Thanks [@LiranCohen](https://github.com/LiranCohen)! - Enable EventEmitterStream

- [#956](https://github.com/TBD54566975/web5-js/pull/956) [`e7f5dfe`](https://github.com/TBD54566975/web5-js/commit/e7f5dfec5fc4cff686340a935442342a9383aa34) Thanks [@LiranCohen](https://github.com/LiranCohen)! - Add ability to update the Identity Metadata name field.

- Updated dependencies [[`bd1cb00`](https://github.com/TBD54566975/web5-js/commit/bd1cb00616029b0d18687b597e90d3b7c4dbeae1), [`3f39bf1`](https://github.com/TBD54566975/web5-js/commit/3f39bf1d14cf835a2959b5386a82ff7228d31e6c), [`bfa0417`](https://github.com/TBD54566975/web5-js/commit/bfa0417a2e9fc1300c5e604bea19b75ab1c73645)]:
- @web5/dids@1.2.0
- @web5/common@1.1.0
- @web5/crypto@1.0.6

## 0.7.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/agent/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@web5/agent",
"version": "0.7.4",
"version": "0.8.1",
"type": "module",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
Expand Down
33 changes: 33 additions & 0 deletions packages/agent/src/identity-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,39 @@ export class AgentIdentityApi<TKeyManager extends AgentKeyManager = AgentKeyMana
await this.agent.did.update({ portableDid, tenant: this.agent.agentDid.uri });
}

/**
* Updates the Identity's metadata name field.
*
* @param didUri - The DID URI of the Identity to update.
* @param name - The new name to set for the Identity.
*
* @throws An error if the Identity is not found, name is not provided, or no changes are detected.
*/
public async setMetadataName({ didUri, name }: { didUri: string; name: string }): Promise<void> {
if (!name) {
throw new Error('AgentIdentityApi: Failed to set metadata name due to missing name value.');
}

const identity = await this.get({ didUri });
if (!identity) {
throw new Error(`AgentIdentityApi: Failed to set metadata name due to Identity not found: ${didUri}`);
}

if (identity.metadata.name === name) {
throw new Error('AgentIdentityApi: No changes detected.');
}

// Update the name in the Identity's metadata and store it
await this._store.set({
id : identity.did.uri,
data : { ...identity.metadata, name },
agent : this.agent,
tenant : identity.metadata.tenant,
updateExisting : true,
useCache : true
});
}

/**
* Returns the connected Identity, if one is available.
*
Expand Down
32 changes: 27 additions & 5 deletions packages/agent/src/store-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { Web5PlatformAgent } from './types/agent.js';
import { TENANT_SEPARATOR } from './utils-internal.js';
import { getDataStoreTenant } from './utils-internal.js';
import { DwnInterface, DwnMessageParams } from './types/dwn.js';
import { ProtocolDefinition } from '@tbd54566975/dwn-sdk-js';
import { ProtocolDefinition, RecordsReadReplyEntry } from '@tbd54566975/dwn-sdk-js';

export type DataStoreTenantParams = {
agent: Web5PlatformAgent;
Expand Down Expand Up @@ -151,13 +151,15 @@ export class DwnDataStore<TStoreObject extends Record<string, any> = Jwk> implem

if (updateExisting) {
// Look up the DWN record ID of the object in the store with the given `id`.
const matchingRecordId = await this.lookupRecordId({ id, tenantDid, agent });
if (!matchingRecordId) {
const matchingRecordEntry = await this.getExistingRecordEntry({ id, tenantDid, agent });
if (!matchingRecordEntry) {
throw new Error(`${this.name}: Update failed due to missing entry for: ${id}`);
}

// set the recordId in the messageParams to update the existing record
messageParams.recordId = matchingRecordId;
// set the dateCreated to the existing dateCreated as this is an immutable property
messageParams.recordId = matchingRecordEntry.recordsWrite!.recordId;
messageParams.dateCreated = matchingRecordEntry.recordsWrite!.descriptor.dateCreated;
} else if (preventDuplicates) {
// Look up the DWN record ID of the object in the store with the given `id`.
const matchingRecordId = await this.lookupRecordId({ id, tenantDid, agent });
Expand All @@ -175,7 +177,7 @@ export class DwnDataStore<TStoreObject extends Record<string, any> = Jwk> implem
author : tenantDid,
target : tenantDid,
messageType : DwnInterface.RecordsWrite,
messageParams : { ...this._recordProperties },
messageParams : { ...this._recordProperties, ...messageParams },
dataStream : new Blob([dataBytes], { type: 'application/json' })
});

Expand Down Expand Up @@ -307,6 +309,26 @@ export class DwnDataStore<TStoreObject extends Record<string, any> = Jwk> implem

return recordId;
}

private async getExistingRecordEntry({ id, tenantDid, agent }: {
id: string;
tenantDid: string;
agent: Web5PlatformAgent;
}): Promise<RecordsReadReplyEntry | undefined> {
// Look up the DWN record ID of the object in the store with the given `id`.
const recordId = await this.lookupRecordId({ id, tenantDid, agent });
if (recordId) {
// Read the record from the store.
const { reply: readReply } = await agent.dwn.processRequest({
author : tenantDid,
target : tenantDid,
messageType : DwnInterface.RecordsRead,
messageParams : { filter: { recordId } }
});

return readReply.entry;
}
}
}

export class InMemoryDataStore<TStoreObject extends Record<string, any> = Jwk> implements AgentDataStore<TStoreObject> {
Expand Down
109 changes: 109 additions & 0 deletions packages/agent/tests/identity-api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,115 @@ describe('AgentIdentityApi', () => {
});
});

describe('setMetadataName', () => {
it('should update the name of an Identity', async () => {
const identity = await testHarness.agent.identity.create({
metadata : { name: 'Test Identity' },
didMethod : 'jwk',
didOptions : {
verificationMethods: [{
algorithm: 'Ed25519'
}]
}
});
expect(identity.metadata.name).to.equal('Test Identity');

// sanity fetch the identity
let storedIdentity = await testHarness.agent.identity.get({ didUri: identity.did.uri });
expect(storedIdentity).to.exist;
expect(storedIdentity?.metadata.name).to.equal('Test Identity');

// update the identity
await testHarness.agent.identity.setMetadataName({ didUri: identity.did.uri, name: 'Updated Identity' });

// fetch the updated identity
storedIdentity = await testHarness.agent.identity.get({ didUri: identity.did.uri });
expect(storedIdentity).to.exist;
expect(storedIdentity?.metadata.name).to.equal('Updated Identity');
});

it('should throw if identity does not exist', async () => {
try {
await testHarness.agent.identity.setMetadataName({ didUri: 'did:method:xyz123', name: 'Updated Identity' });
expect.fail('Expected an error to be thrown');
} catch (error: any) {
expect(error.message).to.include('AgentIdentityApi: Failed to set metadata name due to Identity not found');
}
});

it('should throw if name is missing or empty', async () => {
const storeSpy = sinon.spy(testHarness.agent.identity['_store'], 'set');
const identity = await testHarness.agent.identity.create({
metadata : { name: 'Test Identity' },
didMethod : 'jwk',
didOptions : {
verificationMethods: [{
algorithm: 'Ed25519'
}]
}
});

expect(storeSpy.callCount).to.equal(1);

try {
await testHarness.agent.identity.setMetadataName({ didUri: identity.did.uri, name: '' });
expect.fail('Expected an error to be thrown');
} catch (error: any) {
expect(error.message).to.include('Failed to set metadata name due to missing name value');
}

try {
await testHarness.agent.identity.setMetadataName({ didUri: identity.did.uri, name: undefined! });
expect.fail('Expected an error to be thrown');
} catch (error: any) {
expect(error.message).to.include('Failed to set metadata name due to missing name value');
}

// call count should not have changed
expect(storeSpy.callCount).to.equal(1);

// sanity confirm the name did not change
const storedIdentity = await testHarness.agent.identity.get({ didUri: identity.did.uri });
expect(storedIdentity).to.exist;
expect(storedIdentity?.metadata.name).to.equal('Test Identity');
});

it('should throw if the updated name is the same as the current name', async () => {
const identity = await testHarness.agent.identity.create({
metadata : { name: 'Test Identity' },
didMethod : 'jwk',
didOptions : {
verificationMethods: [{
algorithm: 'Ed25519'
}]
}
});

const storeSpy = sinon.spy(testHarness.agent.identity['_store'], 'set');

try {
await testHarness.agent.identity.setMetadataName({ didUri: identity.did.uri, name: 'Test Identity' });
expect.fail('Expected an error to be thrown');
} catch (error: any) {
expect(error.message).to.include('AgentIdentityApi: No changes detected');
}

// confirm set has not been called
expect(storeSpy.notCalled).to.be.true;

// sanity update the name to something else
await testHarness.agent.identity.setMetadataName({ didUri: identity.did.uri, name: 'Updated Identity' });

// confirm set has been called
expect(storeSpy.calledOnce).to.be.true;

// confirm the name was updated
const storedIdentity = await testHarness.agent.identity.get({ didUri: identity.did.uri });
expect(storedIdentity).to.exist;
expect(storedIdentity?.metadata.name).to.equal('Updated Identity');
});
});

describe('connectedIdentity', () => {
it('returns a connected Identity', async () => {
// create multiple identities, some that are connected, and some that are not
Expand Down
8 changes: 8 additions & 0 deletions packages/agent/tests/store-data.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ describe('AgentDataStore', () => {

describe('updateExisting', () => {
it('updates an existing record', async () => {

// Create and import a DID.
let bearerDid = await DidJwk.create();
const importedDid = await testHarness.agent.did.import({
Expand All @@ -723,6 +724,9 @@ describe('AgentDataStore', () => {
}
};

// get the length of the list before updating to confirm that no additional records are added
const listLength = (await testStore.list({ agent: testHarness.agent })).length;

// Update the DID in the store.
await testStore.set({
id : importedDid.uri,
Expand All @@ -736,6 +740,10 @@ describe('AgentDataStore', () => {
const storedDid = await testStore.get({ id: importedDid.uri, agent: testHarness.agent, tenant: testHarness.agent.agentDid.uri });
expect(storedDid!.uri).to.equal(updatedDid.uri);
expect(storedDid!.document).to.deep.equal(updatedDid.document);

// verify that no additional records were added
const updatedListLength = (await testStore.list({ agent: testHarness.agent })).length;
expect(updatedListLength).to.equal(listLength);
});

it('throws an error if the record does not exist', async () => {
Expand Down
7 changes: 7 additions & 0 deletions packages/browser/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# @web5/browser

## 0.0.3

### Patch Changes

- Updated dependencies [[`bd1cb00`](https://github.com/TBD54566975/web5-js/commit/bd1cb00616029b0d18687b597e90d3b7c4dbeae1), [`3f39bf1`](https://github.com/TBD54566975/web5-js/commit/3f39bf1d14cf835a2959b5386a82ff7228d31e6c)]:
- @web5/dids@1.2.0

## 0.0.2

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/browser/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@web5/browser",
"version": "0.0.2",
"version": "0.0.3",
"description": "Web5 tools and features to use in the browser",
"type": "module",
"main": "./dist/esm/index.js",
Expand Down
Loading

0 comments on commit 47286d7

Please sign in to comment.