diff --git a/src/commands/Unban.ts b/src/commands/Unban.ts index c8d087b..f2ca7ba 100644 --- a/src/commands/Unban.ts +++ b/src/commands/Unban.ts @@ -14,6 +14,7 @@ import { PolicyListConfig, PolicyRoomManager, PolicyRuleType, + RoomInviter, RoomResolver, RoomUnbanner, SetRoomMembership, @@ -50,8 +51,10 @@ async function unbanUserFromRooms( setMembership, roomUnbanner, noop, + roomInviter, }: DraupnirUnbanCommandContext, - rule: MatrixGlob + rule: MatrixGlob, + invite: boolean = false ) { await managementRoomOutput.logMessage( LogLevel.INFO, @@ -67,7 +70,8 @@ async function unbanUserFromRooms( await managementRoomOutput.logMessage( LogLevel.DEBUG, "Unban", - `Unbanning ${member.userID} in ${revision.room.toRoomIDOrAlias()}`, + `Unbanning ${member.userID} in ${revision.room.toRoomIDOrAlias()}` + + (invite ? ", and re-inviting them." : ""), revision.room.toRoomIDOrAlias() ); if (!noop) { @@ -75,6 +79,18 @@ async function unbanUserFromRooms( revision.room.toRoomIDOrAlias(), member.userID ); + const inviteResult = await roomInviter.inviteUser( + revision.room, + member.userID + ); + if (isError(inviteResult)) { + await managementRoomOutput.logMessage( + LogLevel.WARN, + "Unban", + `Failed to re-invite ${member.userID} to ${revision.room.toRoomIDOrAlias()}`, + revision.room.toRoomIDOrAlias() + ); + } } else { await managementRoomOutput.logMessage( LogLevel.WARN, @@ -98,6 +114,7 @@ export type DraupnirUnbanCommandContext = { noop: boolean; roomUnbanner: RoomUnbanner; unlistedUserRedactionQueue: UnlistedUserRedactionQueue; + roomInviter: RoomInviter; }; export const DraupnirUnbanCommand = describeCommand({ @@ -140,6 +157,11 @@ export const DraupnirUnbanCommand = describeCommand({ description: "Legacy, now redundant option to unban the user from all rooms.", }, + invite: { + isFlag: true, + description: + "Re-invite the unbanned user to any rooms they were unbanned from.", + }, }, }, async executor( @@ -206,7 +228,11 @@ export const DraupnirUnbanCommand = describeCommand({ if (isStringUserID(rawEnttiy)) { unlistedUserRedactionQueue.removeUser(rawEnttiy); } - await unbanUserFromRooms(context, rule); + await unbanUserFromRooms( + context, + rule, + keywords.getKeywordValue("invite") + ); } return Ok(undefined); }, @@ -225,6 +251,7 @@ DraupnirContextToCommandContextTranslator.registerTranslation( noop: draupnir.config.noop, roomUnbanner: draupnir.clientPlatform.toRoomUnbanner(), unlistedUserRedactionQueue: draupnir.unlistedUserRedactionQueue, + roomInviter: draupnir.clientPlatform.toRoomInviter(), }; } ); diff --git a/test/unit/commands/UnbanCommandTest.ts b/test/unit/commands/UnbanCommandTest.ts index 9abbcc8..68ea738 100644 --- a/test/unit/commands/UnbanCommandTest.ts +++ b/test/unit/commands/UnbanCommandTest.ts @@ -17,6 +17,7 @@ import { PolicyRuleType, PowerLevelsEventContent, Recommendation, + RoomInviter, RoomResolver, RoomUnbanner, describeProtectedRoomsSet, @@ -136,6 +137,11 @@ describe("Test the DraupnirUnbanCommand", function () { noop: false, roomUnbanner, unlistedUserRedactionQueue: createMock(), + roomInviter: createMock({ + async inviteUser() { + return Ok(undefined); + }, + }), }, { rest: ["spam"],