1+ import type { DataStore } from '../../../store/data-store.js' ;
2+ import type { DidResolver } from '../../../did/did-resolver.js' ;
3+ import type { MessageStore } from '../../../store/message-store.js' ;
4+ import type { MethodHandler } from '../../types.js' ;
5+ import type { MessagesGetMessage , MessagesGetReply , MessagesGetReplyEntry } from '../types.js' ;
6+
7+ import { DataStream } from '../../../utils/data-stream.js' ;
8+ import { DwnConstant } from '../../../core/dwn-constant.js' ;
9+ import { Encoder } from '../../../utils/encoder.js' ;
10+ import { MessageReply } from '../../../core/message-reply.js' ;
11+ import { MessagesGet } from '../messages/messages-get.js' ;
12+ import { authenticate , authorize } from '../../../core/auth.js' ;
13+ import { DwnInterfaceName , DwnMethodName , Message } from '../../../core/message.js' ;
14+
15+ type HandleArgs = { tenant : string , message : MessagesGetMessage } ;
16+
17+ export class MessagesGetHandler implements MethodHandler {
18+ constructor ( private didResolver : DidResolver , private messageStore : MessageStore , private dataStore : DataStore ) { }
19+
20+ public async handle ( { tenant, message } : HandleArgs ) : Promise < MessagesGetReply > {
21+ let messagesGet : MessagesGet ;
22+
23+ try {
24+ messagesGet = await MessagesGet . parse ( message ) ;
25+ } catch ( e ) {
26+ return MessageReply . fromError ( e , 400 ) ;
27+ }
28+
29+ try {
30+ await authenticate ( message . authorization , this . didResolver ) ;
31+ await authorize ( tenant , messagesGet ) ;
32+ } catch ( e ) {
33+ return MessageReply . fromError ( e , 401 ) ;
34+ }
35+
36+ const promises : Promise < MessagesGetReplyEntry > [ ] = [ ] ;
37+ const messageCids = new Set ( message . descriptor . messageCids ) ;
38+
39+ for ( const messageCid of messageCids ) {
40+ const promise = this . messageStore . get ( tenant , messageCid )
41+ . then ( message => {
42+ return { messageCid, message } ;
43+ } )
44+ . catch ( _ => {
45+ return { messageCid, message : undefined , error : `Failed to get message ${ messageCid } ` } ;
46+ } ) ;
47+
48+ promises . push ( promise ) ;
49+ }
50+
51+ const messages = await Promise . all ( promises ) ;
52+
53+ // for every message, include associated data as `encodedData` IF:
54+ // * its a RecordsWrite
55+ // * the data size is equal or smaller than the size threshold
56+ //! NOTE: this is somewhat duplicate code that also exists in `StorageController.query`.
57+ for ( const entry of messages ) {
58+ const { message } = entry ;
59+
60+ if ( ! message ) {
61+ continue ;
62+ }
63+
64+ const { interface : messageInterface , method } = message . descriptor ;
65+ if ( messageInterface !== DwnInterfaceName . Records || method !== DwnMethodName . Write ) {
66+ continue ;
67+ }
68+
69+ const dataCid = message . descriptor . dataCid ;
70+ const dataSize = message . descriptor . dataSize ;
71+
72+ if ( dataCid !== undefined && dataSize ! <= DwnConstant . maxDataSizeAllowedToBeEncoded ) {
73+ const messageCid = await Message . getCid ( message ) ;
74+ const result = await this . dataStore . get ( tenant , messageCid , dataCid ) ;
75+
76+ if ( result ) {
77+ const dataBytes = await DataStream . toBytes ( result . dataStream ) ;
78+ entry . encodedData = Encoder . bytesToBase64Url ( dataBytes ) ;
79+ }
80+ }
81+ }
82+
83+ return {
84+ status : { code : 200 , detail : 'OK' } ,
85+ messages
86+ } ;
87+ }
88+ }
0 commit comments