diff --git a/src/MediaSharingApi.ts b/src/MediaSharingApi.ts index 631e57e..28906ca 100644 --- a/src/MediaSharingApi.ts +++ b/src/MediaSharingApi.ts @@ -7,7 +7,7 @@ import { OutboundMessageContext, } from '@aries-framework/core' import { ShareMediaHandler } from './handlers' -import { MediaSharingRecord, SharedMediaItem } from './repository' +import { MediaSharingRecord, SharedMediaItem, SharedMediaItemOptions } from './repository' import { MediaSharingService } from './services' export interface MediaSharingCreateOptions { @@ -22,7 +22,7 @@ export interface MediaSharingShareOptions { recordId: string parentThreadId?: string description?: string - items?: SharedMediaItem[] + items?: SharedMediaItemOptions[] } @injectable() @@ -35,12 +35,12 @@ export class MediaSharingApi { public constructor( dispatcher: Dispatcher, messageSender: MessageSender, - authCodeService: MediaSharingService, + mediaSharingService: MediaSharingService, connectionService: ConnectionService, agentContext: AgentContext ) { this.messageSender = messageSender - this.mediaSharingService = authCodeService + this.mediaSharingService = mediaSharingService this.connectionService = connectionService this.agentContext = agentContext this.registerHandlers(dispatcher) @@ -73,7 +73,7 @@ export class MediaSharingApi { const { message: payload } = await this.mediaSharingService.createMediaShare(this.agentContext, { record: record, - items: options.items, + items: options.items?.map(item => new SharedMediaItem(item)), description: options.description, parentThreadId: options.parentThreadId, }) diff --git a/src/messages/ShareMediaMessage.ts b/src/messages/ShareMediaMessage.ts index 7800873..ab37b78 100644 --- a/src/messages/ShareMediaMessage.ts +++ b/src/messages/ShareMediaMessage.ts @@ -1,5 +1,5 @@ -import { AgentMessage, Attachment, AttachmentData, IsValidMessageType, parseMessageType } from '@aries-framework/core' -import { uuid } from '@aries-framework/core/build/utils/uuid' +import { AgentMessage, IsValidMessageType, parseMessageType } from '@aries-framework/core' +import { Type } from 'class-transformer' import { IsOptional, IsString } from 'class-validator' import { SharedMediaItem } from '../repository' @@ -30,19 +30,7 @@ export class ShareMediaMessage extends AgentMessage { } this.description = options.description - for (const item of options.items) { - const itemId = item.id ?? uuid() - this.addAppendedAttachment( - new Attachment({ - id: itemId, - filename: item.filename, - mimeType: item.mimeType, - byteCount: item.byteCount, - description: item.description, - data: new AttachmentData({ links: [item.uri] }), - }) - ) - } + this.items = options.items } } @@ -50,6 +38,9 @@ export class ShareMediaMessage extends AgentMessage { @IsString() public description?: string + @Type(() => SharedMediaItem) + public items!: SharedMediaItem[] + @IsValidMessageType(ShareMediaMessage.type) public readonly type = ShareMediaMessage.type.messageTypeUri public static readonly type = parseMessageType('https://2060.io/didcomm/media-sharing/0.1/share-media') diff --git a/src/repository/MediaSharingRecord.ts b/src/repository/MediaSharingRecord.ts index e9376bc..8f426a2 100644 --- a/src/repository/MediaSharingRecord.ts +++ b/src/repository/MediaSharingRecord.ts @@ -1,14 +1,37 @@ import { v4 as uuid } from 'uuid' -import { AriesFrameworkError, BaseRecord } from '@aries-framework/core' +import { AriesFrameworkError, Attachment, AttachmentData, BaseRecord } from '@aries-framework/core' import { MediaSharingRole, MediaSharingState } from '../model' +import { AttachmentOptions } from '@aries-framework/core/build/decorators/attachment/Attachment' +import { Exclude } from 'class-transformer' -export interface SharedMediaItem { - id?: string - mimeType?: string - filename?: string - byteCount?: number - description?: string +export interface CipheringInfo { + algorithm: string + parameters: Record +} + +export interface SharedMediaItemOptions extends Omit { uri: string + ciphering?: CipheringInfo + metadata?: Record +} + +export class SharedMediaItem extends Attachment { + + @Exclude() + public get uri() { + return this.data.links ? this.data.links[0] : undefined + } + + public ciphering?: CipheringInfo + public metadata?: Record + + public constructor(options: SharedMediaItemOptions) { + super({ ...options, data: new AttachmentData({ links: [ options?.uri ] })}) + if (options) { + this.ciphering = options.ciphering + this.metadata = options.metadata + } + } } export interface MediaSharingStorageProps { @@ -47,7 +70,7 @@ export class MediaSharingRecord extends BaseRecord { this.threadId = props.threadId this.parentThreadId = props.parentThreadId this.description = props.description - this.items = props.items?.map((item) => ({ ...item, id: item.id ?? uuid() })) ?? [] + this.items = props.items ?? [] if (props.metadata) { Object.keys(props.metadata).forEach((key) => { this.metadata.set(key, props.metadata?.[key]) @@ -82,7 +105,7 @@ export class MediaSharingRecord extends BaseRecord { if (!expectedStates.includes(this.state)) { throw new Error( - `Auth code record is in invalid state ${this.state}. Valid states are: ${expectedStates.join(', ')}.` + `Media sharing record is in invalid state ${this.state}. Valid states are: ${expectedStates.join(', ')}.` ) } } diff --git a/src/services/MediaSharingService.ts b/src/services/MediaSharingService.ts index 52918df..6ede673 100644 --- a/src/services/MediaSharingService.ts +++ b/src/services/MediaSharingService.ts @@ -2,7 +2,7 @@ import { AgentContext, AriesFrameworkError, EventEmitter, MessageHandlerInboundM import { Lifecycle, scoped } from 'tsyringe' import { MediaSharingEventTypes, MediaSharingStateChangedEvent } from '../MediaSharingEvents' -import { MediaSharingRepository, MediaSharingRecord, SharedMediaItem } from '../repository' +import { MediaSharingRepository, MediaSharingRecord } from '../repository' import { ShareMediaMessage } from '../messages' import { ShareMediaHandler } from '../handlers' import { MediaSharingRole, MediaSharingState } from '../model' @@ -103,29 +103,13 @@ export class MediaSharingService { const record = await this.findByThreadId(messageContext.agentContext, message.threadId) - // Auth record record already exists + // Media sharing record already exists if (record) { throw new AriesFrameworkError(`There is already a MediaSharingRecord with thread Id ${message.threadId}`) } else { const connection = messageContext.assertReadyConnection() - const items: SharedMediaItem[] = [] - if (message.appendedAttachments) { - for (const attachment of message.appendedAttachments) { - if (attachment.data.links && attachment.data.links[0]) { - items.push({ - uri: attachment.data.links[0], - id: attachment.id, - mimeType: attachment.mimeType, - filename: attachment.filename, - byteCount: attachment.byteCount, - description: attachment.description, - }) - } - } - } - - if (items.length === 0) { + if (message.items.length === 0) { throw new AriesFrameworkError('There are no valid items in MediaSharingRecord') } @@ -136,7 +120,7 @@ export class MediaSharingService { parentThreadId: messageContext.message.thread?.parentThreadId, state: MediaSharingState.MediaShared, role: MediaSharingRole.Receiver, - items, + items: message.items, description: message.description, }) diff --git a/test/mediasharing.test.ts b/test/mediasharing.test.ts index 5eca063..a9f9df3 100644 --- a/test/mediasharing.test.ts +++ b/test/mediasharing.test.ts @@ -129,14 +129,19 @@ describe('media test', () => { await aliceAgent.modules.media.share({ recordId: aliceRecord.id, - items: [{ uri: 'http://blabla' }], + items: [{ mimeType: 'image/png', uri: 'http://blabla' }], }) recordsAddedByType(bobAgent, MediaSharingRecord) //.pipe(filter((e) => e.state === MediaSharingState.MediaShared)) .subscribe(subjectBob) - const bobThread = await firstValueFrom(subjectBob) - const aliceThread = await firstValueFrom(subjectAlice) + const bobRecord = await firstValueFrom(subjectBob) + await firstValueFrom(subjectAlice) + + expect(bobRecord.items?.length).toBe(1) + expect(bobRecord.items![0].mimeType).toBe('image/png') + expect(bobRecord.items![0].uri).toBe('http://blabla') + }) })