diff --git a/APIs/JSON/validations/conversations_schema_validation.js b/APIs/JSON/validations/conversations_schema_validation.js index 5beb6310..a884fbee 100644 --- a/APIs/JSON/validations/conversations_schema_validation.js +++ b/APIs/JSON/validations/conversations_schema_validation.js @@ -83,6 +83,7 @@ export const conversationsSchemaValidation = { updated_at: Joi.object({ gt: Joi.date(), }), + ids: Joi.array().items(Joi.alternatives().try(Joi.object(), Joi.string())).max(10), }).required(), delete: Joi.object({ id: Joi.string().required(), diff --git a/app/providers/operations/conversation/list/index.js b/app/providers/operations/conversation/list/index.js index e7f126c6..c03ab100 100644 --- a/app/providers/operations/conversation/list/index.js +++ b/app/providers/operations/conversation/list/index.js @@ -10,7 +10,7 @@ class ConversationListOperation { } async perform(ws, options) { - const { limit, updated_at } = options + const { limit, updated_at, ids } = options const normalizedLimit = this.#normalizeLimitParam(limit) const currentUserId = this.sessionService.getSessionUserId(ws) @@ -18,7 +18,7 @@ class ConversationListOperation { const conversations = await this.conversationService.conversationsList( currentUser, - { updatedAt: updated_at }, + { updatedAt: updated_at, ids }, normalizedLimit ) diff --git a/app/providers/repositories/conversation_participants/index.js b/app/providers/repositories/conversation_participants/index.js index c0272847..b6713329 100644 --- a/app/providers/repositories/conversation_participants/index.js +++ b/app/providers/repositories/conversation_participants/index.js @@ -26,6 +26,12 @@ class ConversationParticipantRepository extends BaseRepository { return conversationsParticipants } + async findUserConversationIds(conversationIds, user_id) { + const availableConversationParticipants = await this.findAll({ conversation_id: { $in: conversationIds }, user_id }) + + return availableConversationParticipants.map((participant) => participant.conversation_id) + } + async findParticipantConversations(userId, limit) { const conversationParticipants = await this.findAll({ user_id: userId }, null, limit) diff --git a/app/providers/services/conversation/index.js b/app/providers/services/conversation/index.js index 2a2ebb8c..07c80598 100644 --- a/app/providers/services/conversation/index.js +++ b/app/providers/services/conversation/index.js @@ -41,7 +41,9 @@ class ConversationService { } async conversationsList(user, options, limit) { - const conversationIds = await this.conversationParticipantRepo.findParticipantConversations(user.native_id, limit) + const conversationIds = await (options.ids?.length + ? this.validateConvIdsWhichUserHasAccess(options.ids, user.native_id) + : this.conversationParticipantRepo.findParticipantConversations(user.native_id, limit)) const filterOptions = {} if (options.updatedAt?.gt) { @@ -82,6 +84,15 @@ class ConversationService { return conversationsParticipants.map((participant) => participant.user_id) } + async validateConvIdsWhichUserHasAccess(conversationIds, userId) { + const verifiedConversationIds = await this.conversationParticipantRepo.findUserConversationIds( + conversationIds, + userId + ) + + return verifiedConversationIds + } + async hasAccessToConversation(conversationId, userId) { const result = { conversation: null, asParticipant: false, asOwner: false, participantIds: null } diff --git a/docs/API.md b/docs/API.md index 2af94274..88c3a469 100644 --- a/docs/API.md +++ b/docs/API.md @@ -333,6 +333,10 @@ Later, the subsequent logins can be done via `token`: }, }; +You can also add the `ids` parameter if you need to get the target chat objects. The maximum number of ids in a request is 10. +For example: ["63480e68f4794709f802a2fa", "63480e68f4794709f802a2fy"] + + { response: { id: "54", diff --git a/test/conversations.js b/test/conversations.js index e17441bb..c60a9bb6 100644 --- a/test/conversations.js +++ b/test/conversations.js @@ -653,6 +653,50 @@ describe("Conversation functions", async () => { assert.equal(responseData.response.error, undefined) }) + it("should work with ids", async () => { + const requestData = { + request: { + conversation_list: { + ids: ArrayOfTmpConversaionts, + }, + id: "3_1", + }, + } + + let responseData = await packetJsonProcessor.processMessageOrError("test", JSON.stringify(requestData)) + + responseData = responseData.backMessages.at(0) + + const conversations = responseData.response.conversations + + assert.strictEqual(requestData.request.id, responseData.response.id) + assert.notEqual(responseData.response.conversations, undefined) + assert.equal( + conversations.some((el) => !ArrayOfTmpConversaionts.includes(el._id.toString())), + false + ) + assert.equal(responseData.response.error, undefined) + }) + + it("should fail max ids 10", async () => { + const requestData = { + request: { + conversation_list: { + ids: ["1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"], + }, + id: "3_1", + }, + } + + let responseData = await packetJsonProcessor.processMessageOrError("test", JSON.stringify(requestData)) + + responseData = responseData.backMessages.at(0) + + assert.strictEqual(requestData.request.id, responseData.response.id) + assert.equal(responseData.response.conversations, undefined) + assert.equal(responseData.response.error, '"ids" must contain less than or equal to 10 items') + }) + it("should fail limit exceeded", async () => { await sendLogout("test", currentUserToken) currentUserToken = (await sendLogin("test", "user_1")).response.user.token