Skip to content

Commit b5e3de5

Browse files
authored
Make BanPropagationProtection's unban prompt use the unban command. (#737)
#736.
1 parent d966aed commit b5e3de5

File tree

5 files changed

+101
-269
lines changed

5 files changed

+101
-269
lines changed

src/commands/interface-manager/MatrixPromptForConfirmation.tsx

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ import {
1414
sendMatrixEventsFromDeadDocument,
1515
} from "./MPSMatrixInterfaceAdaptor";
1616
import {
17+
DocumentNode,
1718
MatrixInterfaceAdaptorCallbacks,
1819
MatrixInterfaceCommandDispatcher,
1920
TextPresentationRenderer,
2021
} from "@the-draupnir-project/interface-manager";
2122
import { resultifyBotSDKRequestError } from "matrix-protection-suite-for-matrix-bot-sdk";
22-
import { Logger, Task, Value } from "matrix-protection-suite";
23+
import { Logger, RoomEvent, Task, Value } from "matrix-protection-suite";
2324
import {
2425
MatrixReactionHandler,
2526
ReactionListener,
@@ -69,30 +70,41 @@ export function makeConfirmationPromptListener(
6970
};
7071
}
7172

72-
export const matrixEventsFromConfirmationPrompt = async function (
73-
{ client, clientPlatform, reactionHandler },
74-
{ event },
75-
command,
76-
document
77-
) {
73+
/**
74+
* This utility allows protections to send confirmation prompts that appear like confirmation prompts
75+
* for commands that have been sent without the `--no-confirm` option, but require confirmation.
76+
*/
77+
export async function sendConfirmationPrompt(
78+
{ client, clientPlatform, reactionHandler }: MatrixAdaptorContext,
79+
{
80+
commandDesignator,
81+
readItems,
82+
}: { commandDesignator: string[]; readItems: string[] },
83+
document: DocumentNode,
84+
{
85+
roomID,
86+
event,
87+
}: { roomID?: StringRoomID | undefined; event?: RoomEvent | undefined }
88+
): Promise<Result<void>> {
89+
const roomIDToUse = roomID ?? event?.room_id;
90+
if (roomIDToUse === undefined) {
91+
throw new TypeError(`You must provide either a room ID or an event`);
92+
}
7893
const reactionMap = new Map<string, string>(
7994
Object.entries({ OK: "OK", Cancel: "Cancel" })
8095
);
8196
const sendResult = await sendMatrixEventsFromDeadDocument(
8297
clientPlatform.toRoomMessageSender(),
83-
event.room_id,
98+
roomIDToUse,
8499
document,
85100
{
86101
replyToEvent: event,
87102
additionalContent: reactionHandler.createAnnotation(
88103
COMMAND_CONFIRMATION_LISTENER,
89104
reactionMap,
90105
{
91-
command_designator: command.designator,
92-
read_items: command
93-
.toPartialCommand()
94-
.stream.source.slice(command.designator.length)
95-
.map((p) => TextPresentationRenderer.render(p)),
106+
command_designator: commandDesignator,
107+
read_items: readItems,
96108
}
97109
),
98110
}
@@ -104,8 +116,28 @@ export const matrixEventsFromConfirmationPrompt = async function (
104116
throw new TypeError(`We exepct to have sent at least one event`);
105117
}
106118
return await reactionHandler
107-
.addReactionsToEvent(client, event.room_id, sendResult.ok[0], reactionMap)
119+
.addReactionsToEvent(client, roomIDToUse, sendResult.ok[0], reactionMap)
108120
.then((_) => Ok(undefined), resultifyBotSDKRequestError);
121+
}
122+
123+
export const matrixEventsFromConfirmationPrompt = async function (
124+
adaptorContext,
125+
{ event },
126+
command,
127+
document
128+
) {
129+
return await sendConfirmationPrompt(
130+
adaptorContext,
131+
{
132+
commandDesignator: command.designator,
133+
readItems: command
134+
.toPartialCommand()
135+
.stream.source.slice(command.designator.length)
136+
.map((p) => TextPresentationRenderer.render(p)),
137+
},
138+
document,
139+
{ event }
140+
);
109141
} satisfies MatrixInterfaceAdaptorCallbacks<
110142
MatrixAdaptorContext,
111143
MatrixEventContext

src/commands/unban/Unban.tsx

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ export const DraupnirUnbanCommand = describeCommand({
145145
{
146146
roomInviter,
147147
roomUnbanner,
148-
setPoliciesMatchingMembership,
149148
policyRoomManager,
150149
watchedPolicyRooms,
151150
unlistedUserRedactionQueue,
@@ -160,21 +159,12 @@ export const DraupnirUnbanCommand = describeCommand({
160159
const inviteMembers =
161160
keywords.getKeywordValue<boolean>("invite", false) ?? false;
162161
if (entity instanceof MatrixUserID) {
163-
const membersToUnban = findMembersMatchingGlob(
162+
const unbanInformation = findUnbanInformationForMember(
164163
setRoomMembership,
165-
new MatrixGlob(entity.toString()),
166-
{ inviteMembers }
167-
);
168-
const policyMatchesToRemove = findBanPoliciesMatchingUsers(
169-
setPoliciesMatchingMembership,
164+
entity,
170165
watchedPolicyRooms,
171-
membersToUnban.map((memberRooms) => memberRooms.member)
166+
{ inviteMembers }
172167
);
173-
const unbanInformation = {
174-
policyMatchesToRemove,
175-
membersToUnban,
176-
entity,
177-
};
178168
if (!isNoConfirm) {
179169
return Ok(unbanInformation);
180170
} else {
@@ -229,6 +219,29 @@ DraupnirContextToCommandContextTranslator.registerTranslation(
229219
}
230220
);
231221

222+
export function findUnbanInformationForMember(
223+
setRoomMembership: SetRoomMembership,
224+
entity: MatrixUserID,
225+
watchedPolicyRooms: WatchedPolicyRooms,
226+
{ inviteMembers }: { inviteMembers: boolean }
227+
): UnbanMembersPreview {
228+
const membersToUnban = findMembersMatchingGlob(
229+
setRoomMembership,
230+
new MatrixGlob(entity.toString()),
231+
{ inviteMembers }
232+
);
233+
const policyMatchesToRemove = findBanPoliciesMatchingUsers(
234+
watchedPolicyRooms,
235+
membersToUnban.map((memberRooms) => memberRooms.member)
236+
);
237+
const unbanInformation = {
238+
policyMatchesToRemove,
239+
membersToUnban,
240+
entity,
241+
};
242+
return unbanInformation;
243+
}
244+
232245
function renderPoliciesToRemove(policyMatches: ListMatches[]): DocumentNode {
233246
return (
234247
<fragment>
@@ -298,7 +311,9 @@ function renderMemberRoomsPreview(memberRooms: MemberRooms): DocumentNode {
298311
);
299312
}
300313

301-
function renderUnbanMembersPreview(preview: UnbanMembersPreview): DocumentNode {
314+
export function renderUnbanMembersPreview(
315+
preview: UnbanMembersPreview
316+
): DocumentNode {
302317
return (
303318
<fragment>
304319
{preview.entity.isContainingGlobCharacters() ? (

src/commands/unban/UnbanUsers.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
SetRoomMembership,
1515
MembershipChange,
1616
Membership,
17-
SetMembershipPolicyRevision,
1817
WatchedPolicyRooms,
1918
PolicyRule,
2019
Recommendation,
@@ -83,7 +82,6 @@ export function findMembersMatchingGlob(
8382
return [...map.values()];
8483
}
8584
export function findBanPoliciesMatchingUsers(
86-
setMembershipPolicies: SetMembershipPolicyRevision,
8785
watchedPolicyRooms: WatchedPolicyRooms,
8886
users: StringUserID[]
8987
): ListMatches[] {

0 commit comments

Comments
 (0)