From d9b8623178b2a9f8dd7fae8ccfd3569e1e80d7b7 Mon Sep 17 00:00:00 2001 From: sksadjad Date: Thu, 14 Mar 2024 19:43:28 +0100 Subject: [PATCH] feat: (WIP) added ownerId, tenantId, and origin. --- .../shared/contactManagerAgentLogic.ts | 22 +++-- .../src/agent/ContactManager.ts | 4 + .../src/__tests__/contact.entities.test.ts | 85 +++++++++++-------- .../src/__tests__/contact.store.test.ts | 54 ++++++------ .../src/entities/contact/ConnectionEntity.ts | 6 ++ .../contact/CorrelationIdentifierEntity.ts | 6 ++ .../entities/contact/DidAuthConfigEntity.ts | 6 ++ .../contact/ElectronicAddressEntity.ts | 6 ++ .../src/entities/contact/IdentityEntity.ts | 13 ++- .../entities/contact/NaturalPersonEntity.ts | 6 ++ .../entities/contact/OpenIdConfigEntity.ts | 6 ++ .../entities/contact/OrganizationEntity.ts | 6 ++ .../src/entities/contact/PartyEntity.ts | 6 ++ .../contact/PartyRelationshipEntity.ts | 6 ++ .../entities/contact/PhysicalAddressEntity.ts | 6 ++ .../migrations/generic/8-CreateContacts.ts | 66 ++++++++++++++ .../src/migrations/generic/index.ts | 3 +- .../postgres/1710438363001-CreateContacts.ts | 43 ++++++++++ .../sqlite/1710438363002-CreateContacts.ts | 41 +++++++++ .../data-store/src/types/contact/contact.ts | 42 +++++++-- .../src/utils/contact/MappingUtils.ts | 79 +++++++++++++---- .../oid4vci-holder/src/agent/OID4VCIHolder.ts | 19 +++-- 22 files changed, 428 insertions(+), 103 deletions(-) create mode 100644 packages/data-store/src/migrations/generic/8-CreateContacts.ts create mode 100644 packages/data-store/src/migrations/postgres/1710438363001-CreateContacts.ts create mode 100644 packages/data-store/src/migrations/sqlite/1710438363002-CreateContacts.ts diff --git a/packages/contact-manager/__tests__/shared/contactManagerAgentLogic.ts b/packages/contact-manager/__tests__/shared/contactManagerAgentLogic.ts index 24360968e..eb0fd8c62 100644 --- a/packages/contact-manager/__tests__/shared/contactManagerAgentLogic.ts +++ b/packages/contact-manager/__tests__/shared/contactManagerAgentLogic.ts @@ -1,10 +1,11 @@ -import { TAgent } from '@veramo/core' +import {TAgent} from '@veramo/core' import { CorrelationIdentifierEnum, + CredentialRole, ElectronicAddress, GetPartiesArgs, Identity, - IdentityRoleEnum, + IdentityOrigin, NaturalPerson, NonPersistedElectronicAddress, NonPersistedIdentity, @@ -14,7 +15,7 @@ import { PartyTypeEnum, PhysicalAddress, } from '../../../data-store/src' -import { AddContactArgs, IContactManager } from '../../src' +import {AddContactArgs, IContactManager} from '../../src' type ConfiguredAgent = TAgent @@ -43,7 +44,8 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro const correlationId = 'default_example_did' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -237,7 +239,8 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro const correlationId = 'new_example_did' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -261,7 +264,8 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro const correlationId = 'missing_connection_add_example' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.URL, correlationId, @@ -277,7 +281,8 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro const correlationId = 'missing_connection_update_example' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -293,7 +298,8 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro const correlationId = 'new_update_example_did' const identity: NonPersistedIdentity = { alias: 'update_example_did', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'update_example_did', diff --git a/packages/contact-manager/src/agent/ContactManager.ts b/packages/contact-manager/src/agent/ContactManager.ts index ed21d79d4..84f911d22 100644 --- a/packages/contact-manager/src/agent/ContactManager.ts +++ b/packages/contact-manager/src/agent/ContactManager.ts @@ -46,6 +46,7 @@ import { UpdatePhysicalAddressArgs, UpdateRelationshipArgs, } from '../types/IContactManager' +import {IdentityOrigin} from "@sphereon/ssi-sdk.data-store/dist"; /** * {@inheritDoc IContactManager} @@ -141,6 +142,9 @@ export class ContactManager implements IAgentPlugin { /** {@inheritDoc IContactManager.cmAddIdentity} */ private async cmAddIdentity(args: AddIdentityArgs, context: RequiredContext): Promise { const { contactId, identity } = args + if(!identity.origin) { + identity.origin = IdentityOrigin.EXTRERNAL + } return this.store.addIdentity({ partyId: contactId, identity }) } diff --git a/packages/data-store/src/__tests__/contact.entities.test.ts b/packages/data-store/src/__tests__/contact.entities.test.ts index e19aff8da..6e4e3329d 100644 --- a/packages/data-store/src/__tests__/contact.entities.test.ts +++ b/packages/data-store/src/__tests__/contact.entities.test.ts @@ -1,23 +1,23 @@ -import { DataSource, FindOptionsWhere } from 'typeorm' -import { DataStoreContactEntities, DataStoreMigrations } from '../index' -import { BaseContactEntity } from '../entities/contact/BaseContactEntity' -import { ConnectionEntity } from '../entities/contact/ConnectionEntity' -import { CorrelationIdentifierEntity } from '../entities/contact/CorrelationIdentifierEntity' -import { DidAuthConfigEntity } from '../entities/contact/DidAuthConfigEntity' -import { ElectronicAddressEntity } from '../entities/contact/ElectronicAddressEntity' -import { IdentityEntity } from '../entities/contact/IdentityEntity' -import { IdentityMetadataItemEntity } from '../entities/contact/IdentityMetadataItemEntity' -import { NaturalPersonEntity } from '../entities/contact/NaturalPersonEntity' -import { OpenIdConfigEntity } from '../entities/contact/OpenIdConfigEntity' -import { OrganizationEntity } from '../entities/contact/OrganizationEntity' -import { PartyEntity } from '../entities/contact/PartyEntity' -import { PartyRelationshipEntity } from '../entities/contact/PartyRelationshipEntity' -import { PartyTypeEntity } from '../entities/contact/PartyTypeEntity' -import { PhysicalAddressEntity } from '../entities/contact/PhysicalAddressEntity' +import {DataSource, FindOptionsWhere} from 'typeorm' +import {DataStoreContactEntities, DataStoreMigrations, IdentityOrigin} from '../index' +import {BaseContactEntity} from '../entities/contact/BaseContactEntity' +import {ConnectionEntity} from '../entities/contact/ConnectionEntity' +import {CorrelationIdentifierEntity} from '../entities/contact/CorrelationIdentifierEntity' +import {DidAuthConfigEntity} from '../entities/contact/DidAuthConfigEntity' +import {ElectronicAddressEntity} from '../entities/contact/ElectronicAddressEntity' +import {IdentityEntity} from '../entities/contact/IdentityEntity' +import {IdentityMetadataItemEntity} from '../entities/contact/IdentityMetadataItemEntity' +import {NaturalPersonEntity} from '../entities/contact/NaturalPersonEntity' +import {OpenIdConfigEntity} from '../entities/contact/OpenIdConfigEntity' +import {OrganizationEntity} from '../entities/contact/OrganizationEntity' +import {PartyEntity} from '../entities/contact/PartyEntity' +import {PartyRelationshipEntity} from '../entities/contact/PartyRelationshipEntity' +import {PartyTypeEntity} from '../entities/contact/PartyTypeEntity' +import {PhysicalAddressEntity} from '../entities/contact/PhysicalAddressEntity' import { ConnectionTypeEnum, CorrelationIdentifierEnum, - IdentityRoleEnum, + CredentialRole, NaturalPerson, NonPersistedConnection, NonPersistedDidAuthConfig, @@ -397,7 +397,8 @@ describe('Database entities tests', (): void => { const alias = 'non_unique_alias' const identity1: NonPersistedIdentity = { alias, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'unique_correlationId1', @@ -408,7 +409,8 @@ describe('Database entities tests', (): void => { const identity2: NonPersistedIdentity = { alias: alias, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'unique_correlationId2', @@ -424,7 +426,8 @@ describe('Database entities tests', (): void => { const correlationId = 'non_unique_correlationId' const identity1: NonPersistedIdentity = { alias: 'unique_alias1', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -435,7 +438,8 @@ describe('Database entities tests', (): void => { const identity2: NonPersistedIdentity = { alias: 'unique_alias2', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -451,7 +455,8 @@ describe('Database entities tests', (): void => { const correlationId = 'example_did' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -480,7 +485,8 @@ describe('Database entities tests', (): void => { it('should throw error when saving identity with blank alias', async (): Promise => { const identity: NonPersistedIdentity = { alias: '', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did', @@ -495,7 +501,8 @@ describe('Database entities tests', (): void => { it('should throw error when saving identity with blank correlation id', async (): Promise => { const identity: NonPersistedIdentity = { alias: 'example_did', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: '', @@ -511,7 +518,8 @@ describe('Database entities tests', (): void => { const correlationId = 'example_did' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -533,7 +541,8 @@ describe('Database entities tests', (): void => { const correlationId = 'example_did' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -555,7 +564,8 @@ describe('Database entities tests', (): void => { const correlationId = 'example.com' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.URL, correlationId, @@ -600,7 +610,8 @@ describe('Database entities tests', (): void => { const correlationId = 'example.com' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.URL, correlationId, @@ -811,7 +822,8 @@ describe('Database entities tests', (): void => { const correlationId = 'relation_example.com' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.URL, correlationId, @@ -970,7 +982,8 @@ describe('Database entities tests', (): void => { const correlationId = 'relation_example.com' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.URL, correlationId, @@ -1070,7 +1083,8 @@ describe('Database entities tests', (): void => { const correlationId = 'relation_example.com' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.URL, correlationId, @@ -1191,7 +1205,8 @@ describe('Database entities tests', (): void => { const correlationId = 'example_did' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -1217,7 +1232,8 @@ describe('Database entities tests', (): void => { const correlationId = 'example_did' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -1354,7 +1370,8 @@ describe('Database entities tests', (): void => { const correlationId = 'example_did' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, diff --git a/packages/data-store/src/__tests__/contact.store.test.ts b/packages/data-store/src/__tests__/contact.store.test.ts index 14a1dd429..50549c2f2 100644 --- a/packages/data-store/src/__tests__/contact.store.test.ts +++ b/packages/data-store/src/__tests__/contact.store.test.ts @@ -10,7 +10,7 @@ import { GetPhysicalAddressesArgs, GetRelationshipsArgs, Identity, - IdentityRoleEnum, + CredentialRole, NaturalPerson, NonPersistedElectronicAddress, NonPersistedIdentity, @@ -184,7 +184,7 @@ describe('Contact store tests', (): void => { identities: [ { alias: 'test_alias1', - roles: [IdentityRoleEnum.ISSUER], + roles: [CredentialRole.ISSUER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did1', @@ -192,7 +192,7 @@ describe('Contact store tests', (): void => { }, { alias: 'test_alias2', - roles: [IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did2', @@ -200,7 +200,7 @@ describe('Contact store tests', (): void => { }, { alias: 'test_alias3', - roles: [IdentityRoleEnum.HOLDER], + roles: [CredentialRole.HOLDER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did3', @@ -403,7 +403,7 @@ describe('Contact store tests', (): void => { identities: [ { alias: 'test_alias1', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did1', @@ -411,7 +411,7 @@ describe('Contact store tests', (): void => { }, { alias: 'test_alias2', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did2', @@ -446,7 +446,7 @@ describe('Contact store tests', (): void => { identities: [ { alias: 'test_alias1', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.URL, correlationId: 'example_did1', @@ -454,7 +454,7 @@ describe('Contact store tests', (): void => { }, { alias: 'test_alias2', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did2', @@ -486,7 +486,7 @@ describe('Contact store tests', (): void => { const identity1: NonPersistedIdentity = { alias: 'test_alias1', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did1', @@ -497,7 +497,7 @@ describe('Contact store tests', (): void => { const identity2: NonPersistedIdentity = { alias: 'test_alias2', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did2', @@ -575,7 +575,7 @@ describe('Contact store tests', (): void => { const identity: NonPersistedIdentity = { alias: 'test_alias', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did', @@ -609,7 +609,7 @@ describe('Contact store tests', (): void => { const identity: NonPersistedIdentity = { alias: 'test_alias', - roles: [IdentityRoleEnum.HOLDER], + roles: [CredentialRole.HOLDER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did', @@ -649,7 +649,7 @@ describe('Contact store tests', (): void => { const identity1: NonPersistedIdentity = { alias: 'test_alias1', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did1', @@ -660,7 +660,7 @@ describe('Contact store tests', (): void => { const identity2: NonPersistedIdentity = { alias: 'test_alias2', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did2', @@ -698,7 +698,7 @@ describe('Contact store tests', (): void => { const identity1: NonPersistedIdentity = { alias: 'test_alias1', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did1', @@ -709,7 +709,7 @@ describe('Contact store tests', (): void => { const identity2: NonPersistedIdentity = { alias: 'test_alias2', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did2', @@ -744,7 +744,7 @@ describe('Contact store tests', (): void => { const alias = 'test_alias1' const identity1: NonPersistedIdentity = { alias, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did1', @@ -755,7 +755,7 @@ describe('Contact store tests', (): void => { const identity2: NonPersistedIdentity = { alias: 'test_alias2', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did2', @@ -794,7 +794,7 @@ describe('Contact store tests', (): void => { const alias = 'test_alias1' const identity1: NonPersistedIdentity = { alias, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did1', @@ -843,7 +843,7 @@ describe('Contact store tests', (): void => { const identity: NonPersistedIdentity = { alias: 'test_alias', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did', @@ -883,7 +883,7 @@ describe('Contact store tests', (): void => { const correlationId = 'missing_connection_example' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.URL, correlationId, @@ -916,7 +916,7 @@ describe('Contact store tests', (): void => { const correlationId = 'missing_connection_example' const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER, IdentityRoleEnum.HOLDER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER, CredentialRole.HOLDER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId, @@ -950,7 +950,7 @@ describe('Contact store tests', (): void => { const identity: NonPersistedIdentity = { alias: 'example_did', - roles: [IdentityRoleEnum.ISSUER, IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.ISSUER, CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did', @@ -984,7 +984,7 @@ describe('Contact store tests', (): void => { identities: [ { alias: 'test_alias1', - roles: [IdentityRoleEnum.VERIFIER], + roles: [CredentialRole.VERIFIER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did1', @@ -992,7 +992,7 @@ describe('Contact store tests', (): void => { }, { alias: 'test_alias2', - roles: [IdentityRoleEnum.ISSUER], + roles: [CredentialRole.ISSUER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did2', @@ -1000,7 +1000,7 @@ describe('Contact store tests', (): void => { }, { alias: 'test_alias3', - roles: [IdentityRoleEnum.HOLDER], + roles: [CredentialRole.HOLDER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId: 'example_did3', @@ -1014,7 +1014,7 @@ describe('Contact store tests', (): void => { expect(result.roles).toBeDefined() expect(result.roles.length).toEqual(3) - expect(result.roles).toEqual([IdentityRoleEnum.VERIFIER, IdentityRoleEnum.ISSUER, IdentityRoleEnum.HOLDER]) + expect(result.roles).toEqual([CredentialRole.VERIFIER, CredentialRole.ISSUER, CredentialRole.HOLDER]) }) it('should add relationship', async (): Promise => { diff --git a/packages/data-store/src/entities/contact/ConnectionEntity.ts b/packages/data-store/src/entities/contact/ConnectionEntity.ts index 1c4daecf0..bde9639f9 100644 --- a/packages/data-store/src/entities/contact/ConnectionEntity.ts +++ b/packages/data-store/src/entities/contact/ConnectionEntity.ts @@ -13,6 +13,12 @@ export class ConnectionEntity extends BaseEntity { @Column('simple-enum', { name: 'type', enum: ConnectionTypeEnum, nullable: false }) type!: ConnectionTypeEnum + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + + @Column({name:'owner_id', nullable:true}) + ownerId?: string + @OneToOne(() => BaseConfigEntity, (config: OpenIdConfigEntity | DidAuthConfigEntity) => config.connection, { cascade: true, onDelete: 'CASCADE', diff --git a/packages/data-store/src/entities/contact/CorrelationIdentifierEntity.ts b/packages/data-store/src/entities/contact/CorrelationIdentifierEntity.ts index 5bcd4abd6..5152a05a9 100644 --- a/packages/data-store/src/entities/contact/CorrelationIdentifierEntity.ts +++ b/packages/data-store/src/entities/contact/CorrelationIdentifierEntity.ts @@ -16,6 +16,12 @@ export class CorrelationIdentifierEntity extends BaseEntity { @IsNotEmpty({ message: 'Blank correlation ids are not allowed' }) correlationId!: string + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + @OneToOne(() => IdentityEntity, (identity: IdentityEntity) => identity.identifier, { onDelete: 'CASCADE', }) diff --git a/packages/data-store/src/entities/contact/DidAuthConfigEntity.ts b/packages/data-store/src/entities/contact/DidAuthConfigEntity.ts index 29685ba61..2c3ea210e 100644 --- a/packages/data-store/src/entities/contact/DidAuthConfigEntity.ts +++ b/packages/data-store/src/entities/contact/DidAuthConfigEntity.ts @@ -11,4 +11,10 @@ export class DidAuthConfigEntity extends BaseConfigEntity { @Column({ name: 'session_id', length: 255, nullable: false }) sessionId!: string + + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string } diff --git a/packages/data-store/src/entities/contact/ElectronicAddressEntity.ts b/packages/data-store/src/entities/contact/ElectronicAddressEntity.ts index e456f70e4..c849cb2fe 100644 --- a/packages/data-store/src/entities/contact/ElectronicAddressEntity.ts +++ b/packages/data-store/src/entities/contact/ElectronicAddressEntity.ts @@ -35,6 +35,12 @@ export class ElectronicAddressEntity extends BaseEntity { @Column({ name: 'partyId', nullable: true }) partyId?: string + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + @CreateDateColumn({ name: 'created_at', nullable: false }) createdAt!: Date diff --git a/packages/data-store/src/entities/contact/IdentityEntity.ts b/packages/data-store/src/entities/contact/IdentityEntity.ts index 393db54e4..ea485e94e 100644 --- a/packages/data-store/src/entities/contact/IdentityEntity.ts +++ b/packages/data-store/src/entities/contact/IdentityEntity.ts @@ -16,7 +16,7 @@ import { IsNotEmpty, validate, ValidationError } from 'class-validator' import { CorrelationIdentifierEntity } from './CorrelationIdentifierEntity' import { ConnectionEntity } from './ConnectionEntity' import { IdentityMetadataItemEntity } from './IdentityMetadataItemEntity' -import { IdentityRoleEnum, ValidationConstraint } from '../../types' +import { CredentialRole, IdentityOrigin, ValidationConstraint } from '../../types' import { PartyEntity } from './PartyEntity' import { getConstraint } from '../../utils/ValidatorUtils' @@ -34,8 +34,17 @@ export class IdentityEntity extends BaseEntity { @IsNotEmpty({ message: 'Blank aliases are not allowed' }) alias!: string + @Column('simple-enum', { name: 'origin', enum: IdentityOrigin, nullable: false }) + origin!: IdentityOrigin + + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + @Column('simple-array', { name: 'roles', nullable: false }) - roles!: Array + roles!: Array @OneToOne(() => CorrelationIdentifierEntity, (identifier: CorrelationIdentifierEntity) => identifier.identity, { cascade: true, diff --git a/packages/data-store/src/entities/contact/NaturalPersonEntity.ts b/packages/data-store/src/entities/contact/NaturalPersonEntity.ts index b04089bbb..7986b58cb 100644 --- a/packages/data-store/src/entities/contact/NaturalPersonEntity.ts +++ b/packages/data-store/src/entities/contact/NaturalPersonEntity.ts @@ -23,6 +23,12 @@ export class NaturalPersonEntity extends BaseContactEntity { @IsNotEmpty({ message: 'Blank display names are not allowed' }) displayName!: string + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + @BeforeInsert() @BeforeUpdate() async validate(): Promise { diff --git a/packages/data-store/src/entities/contact/OpenIdConfigEntity.ts b/packages/data-store/src/entities/contact/OpenIdConfigEntity.ts index 07871ed4c..3aec6b972 100644 --- a/packages/data-store/src/entities/contact/OpenIdConfigEntity.ts +++ b/packages/data-store/src/entities/contact/OpenIdConfigEntity.ts @@ -23,4 +23,10 @@ export class OpenIdConfigEntity extends BaseConfigEntity { @Column('text', { name: 'client_auth_method', nullable: false }) clientAuthMethod!: 'basic' | 'post' | undefined + + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string } diff --git a/packages/data-store/src/entities/contact/OrganizationEntity.ts b/packages/data-store/src/entities/contact/OrganizationEntity.ts index a48e9d4b1..2bdb8b01a 100644 --- a/packages/data-store/src/entities/contact/OrganizationEntity.ts +++ b/packages/data-store/src/entities/contact/OrganizationEntity.ts @@ -15,6 +15,12 @@ export class OrganizationEntity extends BaseContactEntity { @IsNotEmpty({ message: 'Blank display names are not allowed' }) displayName!: string + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + @OneToOne(() => PartyEntity) @JoinColumn({ name: 'party_id' }) party!: PartyEntity diff --git a/packages/data-store/src/entities/contact/PartyEntity.ts b/packages/data-store/src/entities/contact/PartyEntity.ts index 0c1b00930..9b0898523 100644 --- a/packages/data-store/src/entities/contact/PartyEntity.ts +++ b/packages/data-store/src/entities/contact/PartyEntity.ts @@ -30,6 +30,12 @@ export class PartyEntity extends BaseEntity { @Column({ name: 'uri', length: 255, nullable: true }) uri?: string + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + @OneToMany(() => IdentityEntity, (identity: IdentityEntity) => identity.party, { cascade: true, onDelete: 'CASCADE', diff --git a/packages/data-store/src/entities/contact/PartyRelationshipEntity.ts b/packages/data-store/src/entities/contact/PartyRelationshipEntity.ts index 2cc482262..e0f888d84 100644 --- a/packages/data-store/src/entities/contact/PartyRelationshipEntity.ts +++ b/packages/data-store/src/entities/contact/PartyRelationshipEntity.ts @@ -38,6 +38,12 @@ export class PartyRelationshipEntity { @Column({ name: 'right_id', nullable: false }) rightId!: string + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + @CreateDateColumn({ name: 'created_at', nullable: false }) createdAt!: Date diff --git a/packages/data-store/src/entities/contact/PhysicalAddressEntity.ts b/packages/data-store/src/entities/contact/PhysicalAddressEntity.ts index dcd870b29..529a38e79 100644 --- a/packages/data-store/src/entities/contact/PhysicalAddressEntity.ts +++ b/packages/data-store/src/entities/contact/PhysicalAddressEntity.ts @@ -51,6 +51,12 @@ export class PhysicalAddressEntity extends BaseEntity { @IsNotEmpty({ message: 'Blank building names are not allowed' }) buildingName?: string + @Column({name:'owner_id', nullable:true}) + ownerId?: string + + @Column({name:'tenant_id', nullable:true}) + tenantId?: string + @ManyToOne(() => PartyEntity, (party: PartyEntity) => party.physicalAddresses, { onDelete: 'CASCADE', }) diff --git a/packages/data-store/src/migrations/generic/8-CreateContacts.ts b/packages/data-store/src/migrations/generic/8-CreateContacts.ts new file mode 100644 index 000000000..1c6f4a268 --- /dev/null +++ b/packages/data-store/src/migrations/generic/8-CreateContacts.ts @@ -0,0 +1,66 @@ +import { DatabaseType, MigrationInterface, QueryRunner } from 'typeorm' +import Debug from 'debug' +import {CreateContacts1710438363001} from "../postgres/1710438363001-CreateContacts"; +import {CreateContacts1710438363002} from "../sqlite/1710438363002-CreateContacts"; + +const debug: Debug.Debugger = Debug('sphereon:ssi-sdk:migrations') + +export class CreateContacts1708525189000 implements MigrationInterface { + name = 'CreateContacts1708525189000' + + public async up(queryRunner: QueryRunner): Promise { + debug('migration: updating contact tables') + const dbType: DatabaseType = queryRunner.connection.driver.options.type + + switch (dbType) { + case 'postgres': { + debug('using postgres migration file') + const mig: CreateContacts1710438363001 = new CreateContacts1710438363001() + await mig.up(queryRunner) + debug('Migration statements executed') + return + } + case 'sqlite': + case 'expo': + case 'react-native': { + debug('using sqlite/react-native migration file') + const mig: CreateContacts1710438363002 = new CreateContacts1710438363002() + await mig.up(queryRunner) + debug('Migration statements executed') + return + } + default: + return Promise.reject( + `Migrations are currently only supported for sqlite, react-native, expo and postgres. Was ${dbType}. Please run your database without migrations and with 'migrationsRun: false' and 'synchronize: true' for now` + ) + } + } + + public async down(queryRunner: QueryRunner): Promise { + debug('migration: reverting machine state tables') + const dbType: DatabaseType = queryRunner.connection.driver.options.type + + switch (dbType) { + case 'postgres': { + debug('using postgres migration file') + const mig: CreateContacts1710438363001 = new CreateContacts1710438363001() + await mig.down(queryRunner) + debug('Migration statements executed') + return + } + case 'sqlite': + case 'expo': + case 'react-native': { + debug('using sqlite/react-native migration file') + const mig: CreateContacts1710438363002 = new CreateContacts1710438363002() + await mig.down(queryRunner) + debug('Migration statements executed') + return + } + default: + return Promise.reject( + `Migrations are currently only supported for sqlite, react-native, expo and postgres. Was ${dbType}. Please run your database without migrations and with 'migrationsRun: false' and 'synchronize: true' for now` + ) + } + } +} diff --git a/packages/data-store/src/migrations/generic/index.ts b/packages/data-store/src/migrations/generic/index.ts index 9769074fb..8b8c573f0 100644 --- a/packages/data-store/src/migrations/generic/index.ts +++ b/packages/data-store/src/migrations/generic/index.ts @@ -5,6 +5,7 @@ import { CreateStatusList1693866470000 } from './4-CreateStatusList' import { CreateAuditEvents1701635835330 } from './5-CreateAuditEvents' import { CreateDigitalCredential1708525189000 } from './6-CreateDigitalCredential' import { CreateMachineStateStore1708098041262 } from './7-CreateMachineStateStore' +import { CreateContacts1708525189000 } from './8-CreateContacts' /** * The migrations array that SHOULD be used when initializing a TypeORM database connection. @@ -15,7 +16,7 @@ import { CreateMachineStateStore1708098041262 } from './7-CreateMachineStateStor */ // Individual migrations per purpose. Allows parties to not run migrations and thus create/update tables if they are not using a particular feature (yet) -export const DataStoreContactMigrations = [CreateContacts1659463079429, CreateContacts1690925872318] +export const DataStoreContactMigrations = [CreateContacts1659463079429, CreateContacts1690925872318, CreateContacts1708525189000] export const DataStoreIssuanceBrandingMigrations = [CreateIssuanceBranding1659463079429] export const DataStoreStatusListMigrations = [CreateStatusList1693866470000] export const DataStoreEventLoggerMigrations = [CreateAuditEvents1701635835330] diff --git a/packages/data-store/src/migrations/postgres/1710438363001-CreateContacts.ts b/packages/data-store/src/migrations/postgres/1710438363001-CreateContacts.ts new file mode 100644 index 000000000..8d958055d --- /dev/null +++ b/packages/data-store/src/migrations/postgres/1710438363001-CreateContacts.ts @@ -0,0 +1,43 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class CreateContacts1710438363001 implements MigrationInterface { + name = 'CreateContacts1710438363001' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TYPE "identity_origin_type" AS ENUM('INTERNAL', 'EXTERNAL')`) + + await queryRunner.query(`ALTER TABLE "Party" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "Party" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "Identity" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "Identity" ADD COLUMN "tenant_id" text`); + await queryRunner.query(`ALTER TABLE "Identity" ADD COLUMN "origin" varchar CHECK( "identity_origin_type" IN ('INTERNAL', 'EXTERNAL') ) NOT NULL`); + + await queryRunner.query(`ALTER TABLE "CorrelationIdentifier" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "CorrelationIdentifier" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "Connection" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "Connection" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "BaseConfig" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "BaseConfig" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "BaseContact" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "BaseContact" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "PartyRelationship" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "PartyRelationship" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "ElectronicAddress" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "ElectronicAddress" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "PhysicalAddress" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "PhysicalAddress" ADD COLUMN "tenant_id" text`); + + } + + public async down(queryRunner: QueryRunner): Promise { + // TODO DPP-27 implement downgrade + return Promise.reject(Error(`Downgrade is not yet implemented for ${this.name}`)) + } +} diff --git a/packages/data-store/src/migrations/sqlite/1710438363002-CreateContacts.ts b/packages/data-store/src/migrations/sqlite/1710438363002-CreateContacts.ts new file mode 100644 index 000000000..51af808a3 --- /dev/null +++ b/packages/data-store/src/migrations/sqlite/1710438363002-CreateContacts.ts @@ -0,0 +1,41 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class CreateContacts1710438363002 implements MigrationInterface { + name = 'CreateContacts1710438363002' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "Party" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "Party" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "Identity" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "Identity" ADD COLUMN "tenant_id" text`); + await queryRunner.query(`ALTER TABLE "Identity" ADD COLUMN "origin" varchar CHECK( "origin" IN ('INTERNAL', 'EXTERNAL') ) NOT NULL`); + + await queryRunner.query(`ALTER TABLE "CorrelationIdentifier" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "CorrelationIdentifier" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "Connection" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "Connection" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "BaseConfig" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "BaseConfig" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "BaseContact" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "BaseContact" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "PartyRelationship" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "PartyRelationship" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "ElectronicAddress" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "ElectronicAddress" ADD COLUMN "tenant_id" text`); + + await queryRunner.query(`ALTER TABLE "PhysicalAddress" ADD COLUMN "owner_id" text`); + await queryRunner.query(`ALTER TABLE "PhysicalAddress" ADD COLUMN "tenant_id" text`); + + } + + public async down(queryRunner: QueryRunner): Promise { + // TODO DPP-27 implement downgrade + return Promise.reject(Error(`Downgrade is not yet implemented for ${this.name}`)) + } +} diff --git a/packages/data-store/src/types/contact/contact.ts b/packages/data-store/src/types/contact/contact.ts index 3d42dd873..63c1872fd 100644 --- a/packages/data-store/src/types/contact/contact.ts +++ b/packages/data-store/src/types/contact/contact.ts @@ -3,7 +3,9 @@ import { IIdentifier } from '@veramo/core' export type Party = { id: string uri?: string - roles: Array + ownerId?: string + tenantId?: string + roles: Array identities: Array electronicAddresses: Array physicalAddresses: Array @@ -47,23 +49,28 @@ export type PartialParty = Partial< export type Identity = { id: string alias: string - roles: Array + ownerId?: string + tenantId?: string + origin: IdentityOrigin + roles: Array identifier: CorrelationIdentifier connection?: Connection metadata?: Array createdAt: Date lastUpdatedAt: Date } -export type NonPersistedIdentity = Omit & { +export type NonPersistedIdentity = Omit & { + origin?: IdentityOrigin identifier: NonPersistedCorrelationIdentifier connection?: NonPersistedConnection metadata?: Array } -export type PartialIdentity = Partial> & { +export type PartialIdentity = Partial> & { identifier?: PartialCorrelationIdentifier connection?: PartialConnection metadata?: PartialMetadataItem - roles?: IdentityRoleEnum + origin?: IdentityOrigin + roles?: CredentialRole partyId?: string } @@ -77,6 +84,8 @@ export type PartialMetadataItem = Partial export type CorrelationIdentifier = { id: string + ownerId?: string + tenantId?: string type: CorrelationIdentifierEnum correlationId: string } @@ -85,6 +94,8 @@ export type PartialCorrelationIdentifier = Partial export type Connection = { id: string + ownerId?: string + tenantId?: string type: ConnectionTypeEnum config: ConnectionConfig } @@ -99,6 +110,8 @@ export type OpenIdConfig = { id: string clientId: string clientSecret: string + ownerId?: string + tenantId?: string scopes: Array issuer: string redirectUrl: string @@ -112,6 +125,8 @@ export type DidAuthConfig = { id: string identifier: IIdentifier stateId: string + ownerId?: string + tenantId?: string redirectUrl: string sessionId: string } @@ -130,6 +145,8 @@ export type NaturalPerson = { lastName: string middleName?: string displayName: string + ownerId?: string + tenantId?: string createdAt: Date lastUpdatedAt: Date } @@ -140,6 +157,8 @@ export type Organization = { id: string legalName: string displayName: string + ownerId?: string + tenantId?: string createdAt: Date lastUpdatedAt: Date } @@ -168,6 +187,8 @@ export type PartyRelationship = { id: string leftId: string rightId: string + ownerId?: string + tenantId?: string createdAt: Date lastUpdatedAt: Date } @@ -178,6 +199,8 @@ export type ElectronicAddress = { id: string type: ElectronicAddressType electronicAddress: string + ownerId?: string + tenantId?: string createdAt: Date lastUpdatedAt: Date } @@ -196,6 +219,8 @@ export type PhysicalAddress = { provinceName: string countryCode: string buildingName?: string + ownerId?: string + tenantId?: string createdAt: Date lastUpdatedAt: Date } @@ -208,7 +233,12 @@ export type ElectronicAddressType = 'email' | 'phone' export type PhysicalAddressType = 'home' | 'visit' | 'postal' -export enum IdentityRoleEnum { +export enum IdentityOrigin { + INTERNAL = 'internal', + EXTRERNAL = 'external', +} + +export enum CredentialRole { ISSUER = 'issuer', VERIFIER = 'verifier', HOLDER = 'holder', diff --git a/packages/data-store/src/utils/contact/MappingUtils.ts b/packages/data-store/src/utils/contact/MappingUtils.ts index 8d3b838bb..0ded443e8 100644 --- a/packages/data-store/src/utils/contact/MappingUtils.ts +++ b/packages/data-store/src/utils/contact/MappingUtils.ts @@ -6,6 +6,7 @@ import { DidAuthConfig, ElectronicAddress, Identity, + IdentityOrigin, MetadataItem, NaturalPerson, NonPersistedConnection, @@ -30,21 +31,21 @@ import { PartyType, PhysicalAddress, } from '../../types' -import { PartyEntity } from '../../entities/contact/PartyEntity' -import { IdentityEntity } from '../../entities/contact/IdentityEntity' -import { ElectronicAddressEntity } from '../../entities/contact/ElectronicAddressEntity' -import { PartyRelationshipEntity } from '../../entities/contact/PartyRelationshipEntity' -import { BaseContactEntity } from '../../entities/contact/BaseContactEntity' -import { NaturalPersonEntity } from '../../entities/contact/NaturalPersonEntity' -import { OrganizationEntity } from '../../entities/contact/OrganizationEntity' -import { ConnectionEntity } from '../../entities/contact/ConnectionEntity' -import { BaseConfigEntity } from '../../entities/contact/BaseConfigEntity' -import { CorrelationIdentifierEntity } from '../../entities/contact/CorrelationIdentifierEntity' -import { DidAuthConfigEntity } from '../../entities/contact/DidAuthConfigEntity' -import { IdentityMetadataItemEntity } from '../../entities/contact/IdentityMetadataItemEntity' -import { OpenIdConfigEntity } from '../../entities/contact/OpenIdConfigEntity' -import { PartyTypeEntity } from '../../entities/contact/PartyTypeEntity' -import { PhysicalAddressEntity } from '../../entities/contact/PhysicalAddressEntity' +import {PartyEntity} from '../../entities/contact/PartyEntity' +import {IdentityEntity} from '../../entities/contact/IdentityEntity' +import {ElectronicAddressEntity} from '../../entities/contact/ElectronicAddressEntity' +import {PartyRelationshipEntity} from '../../entities/contact/PartyRelationshipEntity' +import {BaseContactEntity} from '../../entities/contact/BaseContactEntity' +import {NaturalPersonEntity} from '../../entities/contact/NaturalPersonEntity' +import {OrganizationEntity} from '../../entities/contact/OrganizationEntity' +import {ConnectionEntity} from '../../entities/contact/ConnectionEntity' +import {BaseConfigEntity} from '../../entities/contact/BaseConfigEntity' +import {CorrelationIdentifierEntity} from '../../entities/contact/CorrelationIdentifierEntity' +import {DidAuthConfigEntity} from '../../entities/contact/DidAuthConfigEntity' +import {IdentityMetadataItemEntity} from '../../entities/contact/IdentityMetadataItemEntity' +import {OpenIdConfigEntity} from '../../entities/contact/OpenIdConfigEntity' +import {PartyTypeEntity} from '../../entities/contact/PartyTypeEntity' +import {PhysicalAddressEntity} from '../../entities/contact/PhysicalAddressEntity' export const partyEntityFrom = (party: NonPersistedParty): PartyEntity => { const partyEntity: PartyEntity = new PartyEntity() @@ -58,6 +59,8 @@ export const partyEntityFrom = (party: NonPersistedParty): PartyEntity => { : [] partyEntity.partyType = partyTypeEntityFrom(party.partyType) partyEntity.contact = contactEntityFrom(party.contact) + partyEntity.ownerId = party.ownerId + partyEntity.tenantId = party.tenantId return partyEntity } @@ -77,6 +80,8 @@ export const partyFrom = (party: PartyEntity): Party => { relationships: party.relationships ? party.relationships.map((relationship: PartyRelationshipEntity) => partyRelationshipFrom(relationship)) : [], partyType: partyTypeFrom(party.partyType), contact: contactFrom(party.contact), + ownerId: party.ownerId, + tenantId: party.tenantId, createdAt: party.createdAt, lastUpdatedAt: party.lastUpdatedAt, } @@ -112,6 +117,8 @@ export const connectionEntityFrom = (connection: NonPersistedConnection): Connec const connectionEntity: ConnectionEntity = new ConnectionEntity() connectionEntity.type = connection.type connectionEntity.config = configEntityFrom(connection.config) + connectionEntity.ownerId = connection.ownerId + connectionEntity.tenantId = connection.tenantId return connectionEntity } @@ -120,6 +127,8 @@ export const connectionFrom = (connection: ConnectionEntity): Connection => { return { id: connection.id, type: connection.type, + ownerId: connection.ownerId, + tenantId: connection.tenantId, config: configFrom(connection.config), } } @@ -138,6 +147,8 @@ export const correlationIdentifierEntityFrom = (identifier: NonPersistedCorrelat const identifierEntity: CorrelationIdentifierEntity = new CorrelationIdentifierEntity() identifierEntity.type = identifier.type identifierEntity.correlationId = identifier.correlationId + identifierEntity.ownerId = identifier.ownerId + identifierEntity.tenantId = identifier.tenantId return identifierEntity } @@ -147,6 +158,8 @@ export const correlationIdentifierFrom = (identifier: CorrelationIdentifierEntit id: identifier.id, type: identifier.type, correlationId: identifier.correlationId, + ownerId: identifier.ownerId, + tenantId: identifier.tenantId, } } @@ -155,7 +168,8 @@ export const didAuthConfigEntityFrom = (config: NonPersistedDidAuthConfig): DidA didAuthConfig.identifier = config.identifier.did didAuthConfig.redirectUrl = config.redirectUrl didAuthConfig.sessionId = config.sessionId - + didAuthConfig.ownerId = config.ownerId + didAuthConfig.tenantId = config.tenantId return didAuthConfig } @@ -163,6 +177,8 @@ export const electronicAddressEntityFrom = (electronicAddress: NonPersistedElect const electronicAddressEntity: ElectronicAddressEntity = new ElectronicAddressEntity() electronicAddressEntity.type = electronicAddress.type electronicAddressEntity.electronicAddress = electronicAddress.electronicAddress + electronicAddressEntity.ownerId = electronicAddress.ownerId + electronicAddressEntity.tenantId = electronicAddress.tenantId return electronicAddressEntity } @@ -172,6 +188,8 @@ export const electronicAddressFrom = (electronicAddress: ElectronicAddressEntity id: electronicAddress.id, type: electronicAddress.type, electronicAddress: electronicAddress.electronicAddress, + ownerId: electronicAddress.ownerId, + tenantId: electronicAddress.tenantId, createdAt: electronicAddress.createdAt, lastUpdatedAt: electronicAddress.lastUpdatedAt, } @@ -187,6 +205,8 @@ export const physicalAddressEntityFrom = (physicalAddress: NonPersistedPhysicalA physicalAddressEntity.provinceName = physicalAddress.provinceName physicalAddressEntity.countryCode = physicalAddress.countryCode physicalAddressEntity.buildingName = physicalAddress.buildingName + physicalAddressEntity.ownerId = physicalAddress.ownerId + physicalAddressEntity.tenantId = physicalAddress.tenantId return physicalAddressEntity } @@ -202,6 +222,8 @@ export const physicalAddressFrom = (physicalAddress: PhysicalAddressEntity): Phy provinceName: physicalAddress.provinceName, countryCode: physicalAddress.countryCode, buildingName: physicalAddress.buildingName, + ownerId: physicalAddress.ownerId, + tenantId: physicalAddress.tenantId, createdAt: physicalAddress.createdAt, lastUpdatedAt: physicalAddress.lastUpdatedAt, } @@ -210,6 +232,9 @@ export const physicalAddressFrom = (physicalAddress: PhysicalAddressEntity): Phy export const identityEntityFrom = (args: NonPersistedIdentity): IdentityEntity => { const identityEntity: IdentityEntity = new IdentityEntity() identityEntity.alias = args.alias + identityEntity.origin = args.origin ?? IdentityOrigin.EXTRERNAL + identityEntity.ownerId = args.ownerId + identityEntity.tenantId = args.tenantId identityEntity.roles = args.roles identityEntity.identifier = correlationIdentifierEntityFrom(args.identifier) identityEntity.connection = args.connection ? connectionEntityFrom(args.connection) : undefined @@ -222,7 +247,10 @@ export const identityFrom = (identity: IdentityEntity): Identity => { return { id: identity.id, alias: identity.alias, + origin: identity.origin, roles: identity.roles, + tenantId: identity.tenantId, + ownerId: identity.ownerId, identifier: correlationIdentifierFrom(identity.identifier), ...(identity.connection && { connection: connectionFrom(identity.connection) }), metadata: identity.metadata ? identity.metadata.map((item: IdentityMetadataItemEntity) => metadataItemFrom(item)) : [], @@ -253,6 +281,8 @@ export const naturalPersonEntityFrom = (naturalPerson: NonPersistedNaturalPerson naturalPersonEntity.middleName = naturalPerson.middleName naturalPersonEntity.lastName = naturalPerson.lastName naturalPersonEntity.displayName = naturalPerson.displayName + naturalPersonEntity.ownerId = naturalPerson.ownerId + naturalPersonEntity.tenantId = naturalPerson.tenantId return naturalPersonEntity } @@ -264,6 +294,8 @@ export const naturalPersonFrom = (naturalPerson: NaturalPersonEntity): NaturalPe middleName: naturalPerson.middleName, lastName: naturalPerson.lastName, displayName: naturalPerson.displayName, + ownerId: naturalPerson.ownerId, + tenantId: naturalPerson.tenantId, createdAt: naturalPerson.createdAt, lastUpdatedAt: naturalPerson.lastUpdatedAt, } @@ -278,6 +310,8 @@ export const openIdConfigEntityFrom = (config: NonPersistedOpenIdConfig): OpenId openIdConfig.redirectUrl = config.redirectUrl openIdConfig.dangerouslyAllowInsecureHttpRequests = config.dangerouslyAllowInsecureHttpRequests openIdConfig.clientAuthMethod = config.clientAuthMethod + openIdConfig.ownerId = config.ownerId + openIdConfig.tenantId = config.tenantId return openIdConfig } @@ -286,6 +320,8 @@ export const organizationEntityFrom = (organization: NonPersistedOrganization): const organizationEntity: OrganizationEntity = new OrganizationEntity() organizationEntity.legalName = organization.legalName organizationEntity.displayName = organization.displayName + organizationEntity.ownerId = organization.ownerId + organizationEntity.tenantId = organization.tenantId return organizationEntity } @@ -295,6 +331,8 @@ export const organizationFrom = (organization: OrganizationEntity): Organization id: organization.id, legalName: organization.legalName, displayName: organization.displayName, + ownerId: organization.ownerId, + tenantId: organization.tenantId, createdAt: organization.createdAt, lastUpdatedAt: organization.lastUpdatedAt, } @@ -304,7 +342,8 @@ export const partyRelationshipEntityFrom = (relationship: NonPersistedPartyRelat const partyRelationshipEntity: PartyRelationshipEntity = new PartyRelationshipEntity() partyRelationshipEntity.leftId = relationship.leftId partyRelationshipEntity.rightId = relationship.rightId - + partyRelationshipEntity.ownerId = relationship.ownerId + partyRelationshipEntity.tenantId = relationship.tenantId return partyRelationshipEntity } @@ -313,6 +352,8 @@ export const partyRelationshipFrom = (relationship: PartyRelationshipEntity): Pa id: relationship.id, leftId: relationship.leftId, rightId: relationship.rightId, + ownerId: relationship.ownerId, + tenantId: relationship.tenantId, createdAt: relationship.createdAt, lastUpdatedAt: relationship.lastUpdatedAt, } @@ -363,6 +404,8 @@ export const openIdConfigFrom = (config: OpenIdConfigEntity): OpenIdConfig => { redirectUrl: config.redirectUrl, dangerouslyAllowInsecureHttpRequests: config.dangerouslyAllowInsecureHttpRequests, clientAuthMethod: config.clientAuthMethod, + ownerId: config.ownerId, + tenantId: config.tenantId, } } @@ -373,6 +416,8 @@ export const didAuthConfigFrom = (config: DidAuthConfigEntity): DidAuthConfig => stateId: '', // FIXME redirectUrl: config.redirectUrl, sessionId: config.sessionId, + ownerId: config.ownerId, + tenantId: config.tenantId, } } diff --git a/packages/oid4vci-holder/src/agent/OID4VCIHolder.ts b/packages/oid4vci-holder/src/agent/OID4VCIHolder.ts index fc519e8fc..042dbd6b6 100644 --- a/packages/oid4vci-holder/src/agent/OID4VCIHolder.ts +++ b/packages/oid4vci-holder/src/agent/OID4VCIHolder.ts @@ -1,17 +1,18 @@ -import { OpenID4VCIClient } from '@sphereon/oid4vci-client' -import { CredentialSupported, DefaultURISchemes } from '@sphereon/oid4vci-common' +import {OpenID4VCIClient} from '@sphereon/oid4vci-client' +import {CredentialSupported, DefaultURISchemes} from '@sphereon/oid4vci-common' import { CorrelationIdentifierEnum, + CredentialRole, IBasicCredentialLocaleBranding, Identity, - IdentityRoleEnum, + IdentityOrigin, NonPersistedIdentity, Party, } from '@sphereon/ssi-sdk.data-store' -import { IAgentPlugin, VerifiableCredential } from '@veramo/core' -import { computeEntryHash } from '@veramo/utils' -import { v4 as uuidv4 } from 'uuid' -import { OID4VCIMachine } from '../machine/oid4vciMachine' +import {IAgentPlugin, VerifiableCredential} from '@veramo/core' +import {computeEntryHash} from '@veramo/utils' +import {v4 as uuidv4} from 'uuid' +import {OID4VCIMachine} from '../machine/oid4vciMachine' import { AddContactIdentityArgs, AssertValidCredentialsArgs, @@ -204,6 +205,7 @@ export class OID4VCIHolder implements IAgentPlugin { filter: [ { identities: { + origin: IdentityOrigin.EXTRERNAL, identifier: { correlationId, }, @@ -242,7 +244,8 @@ export class OID4VCIHolder implements IAgentPlugin { const correlationId: string = credentialsToAccept[0].correlationId const identity: NonPersistedIdentity = { alias: correlationId, - roles: [IdentityRoleEnum.ISSUER], + origin: IdentityOrigin.EXTRERNAL, + roles: [CredentialRole.ISSUER], identifier: { type: CorrelationIdentifierEnum.DID, correlationId,