diff --git a/src/agent/index.ts b/src/agent/index.ts index 20c48b12..63bc71ba 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -16,7 +16,9 @@ import {DID_PREFIX} from '../@config/constants'; import {DEFAULT_DB_CONNECTION} from '../services/databaseService'; import {IRequiredContext, SupportedDidMethodEnum, TAgentTypes} from '../types'; import {createAgentPlugins} from './plugins'; +import {EventEmitter} from 'events'; import DefaultCallbacks = com.sphereon.crypto.DefaultCallbacks; +import {initializeIdentityCreatedEventListeners} from '../services/identityService'; export const didResolver = new Resolver({ ...getDidEbsiResolver(), @@ -44,5 +46,7 @@ const agent = createAgent({ export default agent; export const agentContext: IRequiredContext = {...agent.context, agent}; - DefaultCallbacks.setCoseCryptoDefault(new CoseCryptoService(agentContext)); + +export const agentEventBus: EventEmitter = (agent as any).eventBus as EventEmitter // agent has an eventBus but it is nog exposing it, it only exposes its events to the agent plugins, but we want them here as well +initializeIdentityCreatedEventListeners() diff --git a/src/services/identityService.ts b/src/services/identityService.ts index 310a04b6..57b599d2 100644 --- a/src/services/identityService.ts +++ b/src/services/identityService.ts @@ -1,5 +1,4 @@ import {IIdentifier, IKey} from '@veramo/core'; -import Debug, {Debugger} from 'debug'; import {APP_ID, DID_PREFIX} from '../@config/constants'; @@ -12,12 +11,15 @@ import { IdentifierAliasEnum, IDispatchIdentifierArgs, IRequiredContext, - KeyManagementSystemEnum, SupportedDidMethodEnum, } from '../types'; import {sphereonKeyManager} from '../agent/plugins'; +import {OID4VCIHolderEvent} from '@sphereon/ssi-sdk.oid4vci-holder'; +import {agentEventBus} from '../agent'; +import {Siopv2HolderEvent} from '@sphereon/ssi-sdk.siopv2-oid4vp-op-auth'; +import {Loggers} from '@sphereon/ssi-types'; -const debug: Debugger = Debug(`${APP_ID}:identity`); +const logger = Loggers.DEFAULT.get(`${APP_ID}:identity`); export const getIdentifiers = async (context: IRequiredContext): Promise => { // TODO fully implement @@ -37,6 +39,24 @@ export const createIdentifier = async (args: ICreateIdentifierArgs, context: IRe return identifier; }; + +export const initializeIdentityCreatedEventListeners = () => { + agentEventBus.addListener(OID4VCIHolderEvent.IDENTIFIER_CREATED, args => { + logger.debug('Received OID4VCIHolderEvent.IDENTIFIER_CREATED event, dispatching the new identifier', args.identifier) + dispatchIdentifier({identifier: args.identifier}).then(value => { + logger.debug('identifier linked to the active user') + }) + }) + agentEventBus.addListener(Siopv2HolderEvent.IDENTIFIER_CREATED, args => { + logger.debug('Received Siopv2HolderEvent.IDENTIFIER_CREATED event, dispatching the new identifier', args.result) + dispatchIdentifier({identifier: args.result}).then(value => { + logger.debug('identifier linked to the active user') + }) + }) +} + + + export const dispatchIdentifier = async (args: IDispatchIdentifierArgs): Promise => { const {identifier} = args; if (store.getState().user.users.size > 0) { @@ -60,7 +80,7 @@ export const getOrCreatePrimaryIdentifier = async (args: ICreateOrGetIdentifierA args?.createOpts?.options?.type === undefined || identifier.keys.some((key: IKey) => key.type === args?.createOpts?.options?.type), ); - debug(`Currently available identifiers for ${args?.method} / ${args?.createOpts?.options?.type}: ${identifiers.length}`); + logger.debug(`Currently available identifiers for ${args?.method} / ${args?.createOpts?.options?.type}: ${identifiers.length}`); // Currently we only support one identifier @@ -71,6 +91,6 @@ export const getOrCreatePrimaryIdentifier = async (args: ICreateOrGetIdentifierA } const identifier: IIdentifier = !identifiers || identifiers.length == 0 ? await createIdentifier(args, context) : identifiers[0]; - debug(`identifier: ${JSON.stringify(identifier, null, 2)}`); + logger.debug(`identifier: ${JSON.stringify(identifier, null, 2)}`); return await context.agent.didManagerGet({did: identifier.did}); }; diff --git a/src/store/actions/user.actions.ts b/src/store/actions/user.actions.ts index 44fa592a..15bf2875 100644 --- a/src/store/actions/user.actions.ts +++ b/src/store/actions/user.actions.ts @@ -69,21 +69,30 @@ export const getUsers = (): ThunkAction, RootState, unknown, Actio export const addIdentifier = (args: IAddIdentifierArgs): ThunkAction, RootState, unknown, Action> => { return async (dispatch: ThunkDispatch, getState: CombinedState) => { dispatch({type: USERS_LOADING}); - const userSate: IUserState = getState().user; + const userState: IUserState = getState().user; + const user: IUser = userState.users.values().next().value; + + // Check if identifier already exists + const isDuplicate = user.identifiers.some(identifier => identifier.did === args.did); + if (isDuplicate) { + return; + } + const userIdentifier = { did: args.did, createdAt: new Date(), lastUpdatedAt: new Date(), }; + // We are currently only supporting a single user right now - const user: IUser = { - ...userSate.users.values().next().value, - identifiers: [...userSate.users.values().next().value.identifiers, userIdentifier], + const updatedUser: IUser = { + ...user, + identifiers: [...user.identifiers, userIdentifier], }; - userServiceUpdateUser(user) - .then((user: IUser) => dispatch({type: UPDATE_USER_SUCCESS, payload: user})) - .catch(() => dispatch({type: UPDATE_USER_FAILED})); + userServiceUpdateUser(updatedUser) + .then((user: IUser) => dispatch({type: UPDATE_USER_SUCCESS, payload: user})) + .catch(() => dispatch({type: UPDATE_USER_FAILED})); }; };