From ded323daf135bc1d3628a2d2501aab16c0f3e1a4 Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Sun, 28 Jan 2024 18:10:46 +0530 Subject: [PATCH 1/4] feat:revoke user from board access Signed-off-by: brf153 <153hsb@gmail.com> --- whiteboard/blocks/UtilityBlock.ts | 2 +- whiteboard/lib/commandUtility.ts | 112 +++++++++++++++++------------- whiteboard/lib/messages.ts | 39 +++++++++++ 3 files changed, 103 insertions(+), 50 deletions(-) diff --git a/whiteboard/blocks/UtilityBlock.ts b/whiteboard/blocks/UtilityBlock.ts index 6db1a31267..4a54072f98 100644 --- a/whiteboard/blocks/UtilityBlock.ts +++ b/whiteboard/blocks/UtilityBlock.ts @@ -176,7 +176,7 @@ export async function permissionHeaderBlock( let markdownBlock: SectionBlock; markdownBlock = getMarkdownBlock( - `${userForBoardPermission} wants to edit *${boardname}*` + `*${userForBoardPermission}* wants to edit *${boardname}*` ); const actionBlock = getActionsBlock(UtilityEnum.PERMISSION_BLOCK_ID, [ diff --git a/whiteboard/lib/commandUtility.ts b/whiteboard/lib/commandUtility.ts index bf5833ad3f..b5a5d9e632 100644 --- a/whiteboard/lib/commandUtility.ts +++ b/whiteboard/lib/commandUtility.ts @@ -12,6 +12,7 @@ import { WhiteboardApp } from "../WhiteboardApp"; import { handleListCommand, helperMessage, + removeUserFromBoardOwner, sendMessage, sendMessageWithAttachment, } from "./messages"; @@ -26,12 +27,7 @@ import { import { randomId } from "./utilts"; import { defaultPreview } from "../assets/defaultPreview"; -import { - checkBoardNameByRoomId, - getMessageIdByBoardName, - deleteBoardByMessageId, -} from "../persistence/boardInteraction"; -import { IMessage } from "@rocket.chat/apps-engine/definition/messages"; +import {checkBoardNameByRoomId, getMessageIdByBoardName, deleteBoardByMessageId, getBoardRecordByRoomId} from '../persistence/boardInteraction'; //CommandUtility is used to handle the commands export class CommandUtility implements ExecutorProps { @@ -82,8 +78,6 @@ export class CommandUtility implements ExecutorProps { for(const user of users){ if(user.roles.includes('admin') || user.roles.includes('owner') || user.roles.includes('moderator')){ if(sender.username != user.username){ - - // console.log("here again", user, sender.username) boardOwner.push(user) } @@ -157,24 +151,6 @@ export class CommandUtility implements ExecutorProps { headerBlock ); - console.log("MessageId", messageId); - - // const headerBlockAfterPermission = await buildHeaderBlockAfterPermission( - // sender.username, - // boardURL, - // appId, - // name - // ) - // const message = await this.modify - // .getUpdater() - // .message(messageId, sender); - // message.setBlocks(headerBlockAfterPermission) - // for(let user of boardOwner){ - - // await this.modify.getNotifier().notifyUser(user, message.getMessage()); - // // await this.modify.getUpdater().finish(message); - // } - storeBoardRecord( persistence, room.id, @@ -339,26 +315,64 @@ export class CommandUtility implements ExecutorProps { } } - // private async checkCommand() { - // const appId = this.app.getID(); - // const user = this.context.getSender(); - // const params = this.context.getArguments(); - // const room: IRoom = this.context.getRoom(); - // const appSender: IUser = (await this.read - // .getUserReader() - // .getAppUser()) as IUser; - // const attachments = [ - // { - // collapsed: true, - // color: "#00000000", - // imageUrl: defaultPreview, - // }, - // ]; - - // const message:IMessage = {text:"Board Here", room:room, sender:appSender, pinned:true, attachments:attachments} - - // await this.read.getNotifier().notifyRoom(room, message); - // } + // denyUser is used to handle the /whiteboard deny {userName} of {boardName} command + private async denyUser() { + + const user = this.context.getSender(); + const params = this.context.getArguments(); + const room: IRoom = this.context.getRoom(); + const appSender: IUser = (await this.read + .getUserReader() + .getAppUser()) as IUser; + + // the name specified in command "/whiteboard delete" + const requiredParams = params.slice(1) + const index = requiredParams.indexOf('of') + const userName = requiredParams.slice(0,index).join(" ").trim() + const boardName = requiredParams.slice(index+1).join(" ").trim() + + // Get the board data from the database + const boardData = await getBoardRecordByRoomId(this.read.getPersistenceReader(), room.id) + let requiredBoardData; + for (let i = 0; i < boardData.length; i++) { + if (boardData[i].title == boardName) { + requiredBoardData = boardData[i] + break; + } + } + + console.log("requiredBoardData", requiredBoardData) + // If board not found + if(!requiredBoardData){ + const message = {room: room, sender: appSender, text: "Board not found"} + return this.read.getNotifier().notifyUser(user, message); + } + // If board found + else{ + // check whether the user is admin or board Owner or not + const match = requiredBoardData.boardOwner.find(obj => obj.id === user.id) + console.log("match", match) + if(match){ + console.log("User is admin or board Owner") + // if the user is admin or board Owner + const response = await removeUserFromBoardOwner(this.room, this.persistence, userName, requiredBoardData) + if(response !== undefined){ + const message = {room: room, sender: appSender, text: `**${userName}** has been removed from the rights of **${boardName}**.`} + return this.read.getNotifier().notifyUser(user, message); + } + else{ + const message = {room: room, sender: appSender, text: "Some error occured!"} + return this.read.getNotifier().notifyUser(user, message); + } + + } + else{ + // if the user is not admin or board Owner + const message = {room: room, sender: appSender, text: "You are not authorized to perform this action"} + return this.read.getNotifier().notifyUser(user, message); + } + } + } public async resolveCommand(context: WhiteboardSlashCommandContext) { switch (this.command[0]) { @@ -374,9 +388,9 @@ export class CommandUtility implements ExecutorProps { case "delete": await this.deleteBoardCommand(); break; - // case "check": - // await this.checkCommand(); - // break; + case "deny": + await this.denyUser(); + break; default: const appSender: IUser = (await this.read .getUserReader() diff --git a/whiteboard/lib/messages.ts b/whiteboard/lib/messages.ts index cd957f92a0..d3ace56c44 100644 --- a/whiteboard/lib/messages.ts +++ b/whiteboard/lib/messages.ts @@ -356,3 +356,42 @@ export async function addUsertoBoardOwner( return undefined } } + + +// function to remove user from boardRights +export const removeUserFromBoardOwner = async ( + room: IRoom, + persistance: IPersistence, + userName: string, + board: any, +) => { + + // Add the user to the boardOwner + const boardOwners = board.boardOwner + + console.log("name", userName) + // Filter the user from the boardOwner + const boardOwnerArray = boardOwners.filter((boardOwner) => boardOwner.username !== userName) + + + console.log("boardOwnerArray", boardOwnerArray) + if(boardOwnerArray === boardOwners){ + return undefined + } + else{ + // Update the boardData in the database + await storeBoardRecord( + persistance, + room.id, + board.id, + board.boardData, + board.messageId, + board.cover, + board.title, + board.privateMessageId, + board.status, + boardOwnerArray + ) + return boardOwnerArray + } +} \ No newline at end of file From c8b16f5d9913bb5f6f146f599fca037fc1a7d823 Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Sun, 28 Jan 2024 18:14:16 +0530 Subject: [PATCH 2/4] code cleaned Signed-off-by: brf153 <153hsb@gmail.com> --- .../handlers/ExecuteViewSubmitHandler.ts | 36 +++++-------------- whiteboard/lib/commandUtility.ts | 4 --- whiteboard/lib/messages.ts | 3 -- whiteboard/persistence/boardInteraction.ts | 1 - 4 files changed, 8 insertions(+), 36 deletions(-) diff --git a/whiteboard/handlers/ExecuteViewSubmitHandler.ts b/whiteboard/handlers/ExecuteViewSubmitHandler.ts index 47481bdfa5..903b06d956 100644 --- a/whiteboard/handlers/ExecuteViewSubmitHandler.ts +++ b/whiteboard/handlers/ExecuteViewSubmitHandler.ts @@ -47,7 +47,6 @@ export class ExecuteViewSubmitHandler { .getAppUser()) as IUser; const appId = AppSender.appId; try { - console.log("View Id: ", view); switch (view.id) { // This case is used to handle the submit interaction from the settings modal case UtilityEnum.SETTINGS_MODAL_ID: @@ -400,7 +399,6 @@ export class ExecuteViewSubmitHandler { const messageId = this.context.getInteractionData().view.submit ?.value; - // console.log("MessageId inside Delete Modal ID", messageId) if (messageId) { // Board data is deleted from database const boardName = await deleteBoardByMessageId( @@ -445,46 +443,32 @@ export class ExecuteViewSubmitHandler { .getInteractionResponder() .successResponse(); - // case UtilityEnum.EDIT_MODAL_ID: - // const boardURL = this.context.getInteractionData().view.submit?.url - // console.log("boardURL", boardURL) - // if(boardURL){ - // this.http.get(boardURL) - // } - // return this.context - // .getInteractionResponder() - // .successResponse(); - case UtilityEnum.PERMISSION_MODAL_ID: const boardMessageId = this.context.getInteractionData().view.submit ?.value; - // console.log("MessageId inside Permission Modal ID", messageId) if(boardMessageId){ const room = await this.read .getMessageReader() .getRoom(boardMessageId); if(room){ - // console.log("Checking interaction data", this.context.getInteractionData().view.submit?.value) + const boardData = await getBoardRecordByMessageId(this.read.getPersistenceReader(), boardMessageId) - // console.log("Board data", boardData) + for(let i=0; i obj.id === user.id) - console.log("match", match) if(match){ - console.log("User is admin or board Owner") // if the user is admin or board Owner const response = await removeUserFromBoardOwner(this.room, this.persistence, userName, requiredBoardData) if(response !== undefined){ diff --git a/whiteboard/lib/messages.ts b/whiteboard/lib/messages.ts index d3ace56c44..15601c1574 100644 --- a/whiteboard/lib/messages.ts +++ b/whiteboard/lib/messages.ts @@ -369,12 +369,9 @@ export const removeUserFromBoardOwner = async ( // Add the user to the boardOwner const boardOwners = board.boardOwner - console.log("name", userName) // Filter the user from the boardOwner const boardOwnerArray = boardOwners.filter((boardOwner) => boardOwner.username !== userName) - - console.log("boardOwnerArray", boardOwnerArray) if(boardOwnerArray === boardOwners){ return undefined } diff --git a/whiteboard/persistence/boardInteraction.ts b/whiteboard/persistence/boardInteraction.ts index 9eadf9563c..dd8ea514dd 100644 --- a/whiteboard/persistence/boardInteraction.ts +++ b/whiteboard/persistence/boardInteraction.ts @@ -411,7 +411,6 @@ export const getMessageIdByBoardName = async ( for (const board of boardData) { if (board.title === boardName) { - console.log("Board name mil gaya!"); let messageId = board.messageId; return messageId; } From f90ea516126ed4a5bc120edff87fc51f0884bc9b Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Sun, 28 Jan 2024 18:22:44 +0530 Subject: [PATCH 3/4] updated the readme Signed-off-by: brf153 <153hsb@gmail.com> --- whiteboard/WhiteboardApp.ts | 1 + whiteboard/lib/messages.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/whiteboard/WhiteboardApp.ts b/whiteboard/WhiteboardApp.ts index f63094b2a6..3a4cfa9d0e 100644 --- a/whiteboard/WhiteboardApp.ts +++ b/whiteboard/WhiteboardApp.ts @@ -116,6 +116,7 @@ export class WhiteboardApp extends App implements IUIKitInteractionHandler { \`/whiteboard delete \` - Delete a whiteboard \`/whiteboard help\` - Display helper message \`/whiteboard list\` - List all the board names in the room + \`/whiteboard deny of \` - Deny a user to edit the board You can use \`Create Whiteboard\` Action Button to create a new whiteboard as well \n Refer https://github.com/RocketChat/Apps.Whiteboard documentation for more details 🚀`, persistence diff --git a/whiteboard/lib/messages.ts b/whiteboard/lib/messages.ts index 15601c1574..bc2e316b29 100644 --- a/whiteboard/lib/messages.ts +++ b/whiteboard/lib/messages.ts @@ -183,6 +183,7 @@ export async function helperMessage( \`/whiteboard delete \` - Delete a whiteboard \`/whiteboard help\` - Display helper message \`/whiteboard list\` - List all the board names in the room + \`/whiteboard deny of \` - Deny a user to edit the board You can use \`Create Whiteboard\` Action Button to create a new whiteboard as well \n Refer https://github.com/RocketChat/Apps.Whiteboard for more details 🚀 `; From 01168a136260ba0657777c3ea92765dc0a086485 Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Mon, 29 Jan 2024 03:14:02 +0530 Subject: [PATCH 4/4] code cleaned Signed-off-by: brf153 <153hsb@gmail.com> --- whiteboard/blocks/UtilityBlock.ts | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/whiteboard/blocks/UtilityBlock.ts b/whiteboard/blocks/UtilityBlock.ts index 4a54072f98..f4eae1c502 100644 --- a/whiteboard/blocks/UtilityBlock.ts +++ b/whiteboard/blocks/UtilityBlock.ts @@ -25,24 +25,6 @@ export async function buildHeaderBlock( ButtonStyle.PRIMARY ); - // const settingButton = getButton( - // "Settings", - // UtilityEnum.PREVIEW_BLOCK_ID, - // UtilityEnum.SETTINGS_BUTTON_ACTION_ID, - // appId, - // "Settings", - // undefined - // ); - - // const deleteButton = getDeleteButton( - // "Delete board", - // UtilityEnum.PREVIEW_BLOCK_ID, - // UtilityEnum.DELETE_BUTTON_ACTION_ID, - // appId, - // "Delete", - // ButtonStyle.DANGER - // ); - let markdownBlock: SectionBlock; if (boardname == undefined) { markdownBlock = getMarkdownBlock( @@ -53,9 +35,7 @@ export async function buildHeaderBlock( } const actionBlock = getActionsBlock(UtilityEnum.PREVIEW_BLOCK_ID, [ - // settingButton, - openbutton, - // deleteButton, + openbutton ]); block.push(markdownBlock); block.push(actionBlock);