diff --git a/keyserver/src/responders/message-responders.js b/keyserver/src/responders/message-responders.js --- a/keyserver/src/responders/message-responders.js +++ b/keyserver/src/responders/message-responders.js @@ -9,10 +9,12 @@ messageTypes, type SendTextMessageRequest, type SendMultimediaMessageRequest, + type SendReactionMessageRequest, type FetchMessageInfosResponse, type FetchMessageInfosRequest, defaultNumberPerThread, type SendMessageResponse, + type ReactionMessageData, } from 'lib/types/message-types'; import type { TextMessageData } from 'lib/types/messages/text'; import { threadPermissions } from 'lib/types/thread-types'; @@ -179,15 +181,50 @@ return { newMessageInfo }; } -// eslint-disable-next-line no-unused-vars const sendReactionMessageRequestInputValidator = tShape({ threadID: t.String, targetMessageID: t.String, reaction: t.maybe(t.String), }); +async function reactionMessageCreationResponder( + viewer: Viewer, + input: any, +): Promise { + const request: SendReactionMessageRequest = input; + await validateInput(viewer, sendReactionMessageRequestInputValidator, input); + + const { threadID, targetMessageID, reaction } = request; + + if (!targetMessageID || reaction === undefined) { + throw new ServerError('invalid_parameters'); + } + + const hasPermission = await checkThreadPermission( + viewer, + threadID, + threadPermissions.VOICED, + ); + if (!hasPermission) { + throw new ServerError('invalid_parameters'); + } + + const messageData: ReactionMessageData = { + type: messageTypes.REACTION, + threadID, + creatorID: viewer.id, + time: Date.now(), + targetMessageID, + reaction, + }; + + const rawMessageInfos = await createMessages(viewer, [messageData]); + + return { newMessageInfo: rawMessageInfos[0] }; +} export { textMessageCreationResponder, messageFetchResponder, multimediaMessageCreationResponder, + reactionMessageCreationResponder, };