mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-09-28 20:26:02 +00:00
Allow the redact command to take globs
This commit is contained in:
parent
7de3744875
commit
6753e7f780
@ -19,6 +19,7 @@ import { Mjolnir } from "../Mjolnir";
|
||||
import { LogLevel, LogService } from "matrix-bot-sdk";
|
||||
import { logMessage } from "../LogProxy";
|
||||
import config from "../config";
|
||||
import { isTrueJoinEvent } from "../utils";
|
||||
|
||||
export class FirstMessageIsImage implements IProtection {
|
||||
|
||||
@ -36,14 +37,7 @@ export class FirstMessageIsImage implements IProtection {
|
||||
if (!this.justJoined[roomId]) this.justJoined[roomId] = [];
|
||||
|
||||
if (event['type'] === 'm.room.member') {
|
||||
const membership = event['content']['membership'] || 'join';
|
||||
let prevMembership = "leave";
|
||||
if (event['unsigned'] && event['unsigned']['prev_content']) {
|
||||
prevMembership = event['unsigned']['prev_content']['membership'] || 'leave';
|
||||
}
|
||||
|
||||
// We look at the previous membership to filter out profile changes
|
||||
if (membership === 'join' && prevMembership !== "join") {
|
||||
if (isTrueJoinEvent(event)) {
|
||||
this.justJoined[roomId].push(event['state_key']);
|
||||
LogService.info("FirstMessageIsImage", `Tracking ${event['state_key']} in ${roomId} as just joined`);
|
||||
}
|
||||
|
86
src/utils.ts
86
src/utils.ts
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { MatrixClient } from "matrix-bot-sdk";
|
||||
import { LogService, MatrixClient, MatrixGlob } from "matrix-bot-sdk";
|
||||
|
||||
export function setToArray<T>(set: Set<T>): T[] {
|
||||
const arr: T[] = [];
|
||||
@ -24,7 +24,27 @@ export function setToArray<T>(set: Set<T>): T[] {
|
||||
return arr;
|
||||
}
|
||||
|
||||
export function isTrueJoinEvent(event: any): boolean {
|
||||
const membership = event['content']['membership'] || 'join';
|
||||
let prevMembership = "leave";
|
||||
if (event['unsigned'] && event['unsigned']['prev_content']) {
|
||||
prevMembership = event['unsigned']['prev_content']['membership'] || 'leave';
|
||||
}
|
||||
|
||||
// We look at the previous membership to filter out profile changes
|
||||
return membership === 'join' && prevMembership !== "join";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the events sent by a user (or users if using wildcards) in a given room ID, since
|
||||
* the time they joined.
|
||||
* @param {MatrixClient} client The client to use.
|
||||
* @param {string} sender The sender. Can include wildcards to match multiple people.
|
||||
* @param {string} roomId The room ID to search in.
|
||||
* @returns {Promise<any>} Resolves to the events sent by the user(s) prior to join.
|
||||
*/
|
||||
export async function getMessagesByUserSinceLastJoin(client: MatrixClient, sender: string, roomId: string): Promise<any[]> {
|
||||
const limit = 1000; // maximum number of events to process, regardless of outcome
|
||||
const filter = {
|
||||
room: {
|
||||
rooms: [roomId],
|
||||
@ -33,7 +53,6 @@ export async function getMessagesByUserSinceLastJoin(client: MatrixClient, sende
|
||||
rooms: [roomId],
|
||||
},
|
||||
timeline: {
|
||||
senders: [sender],
|
||||
rooms: [roomId],
|
||||
types: ["m.room.message"],
|
||||
},
|
||||
@ -56,6 +75,22 @@ export async function getMessagesByUserSinceLastJoin(client: MatrixClient, sende
|
||||
},
|
||||
};
|
||||
|
||||
let isGlob = true;
|
||||
if (!sender.includes("*")) {
|
||||
isGlob = false;
|
||||
filter.room.timeline['senders'] = [sender];
|
||||
}
|
||||
|
||||
const matcher = new MatrixGlob(sender);
|
||||
|
||||
function testUser(userId: string): boolean {
|
||||
if (isGlob) {
|
||||
return matcher.test(userId);
|
||||
} else {
|
||||
return userId === sender;
|
||||
}
|
||||
}
|
||||
|
||||
function initialSync() {
|
||||
const qs = {
|
||||
filter: JSON.stringify(filter),
|
||||
@ -69,6 +104,7 @@ export async function getMessagesByUserSinceLastJoin(client: MatrixClient, sende
|
||||
from: from,
|
||||
dir: "b",
|
||||
};
|
||||
LogService.info("utils", "Backfilling with token: " + token);
|
||||
return client.doRequest("GET", `/_matrix/client/r0/rooms/${encodeURIComponent(roomId)}/messages`, qs);
|
||||
}
|
||||
|
||||
@ -76,35 +112,37 @@ export async function getMessagesByUserSinceLastJoin(client: MatrixClient, sende
|
||||
const response = await initialSync();
|
||||
if (!response) return [];
|
||||
|
||||
let token = response['next_batch'];
|
||||
|
||||
const messages = [];
|
||||
const stopProcessingMembers = [];
|
||||
let processed = 0;
|
||||
|
||||
const timeline = (((response['rooms'] || {})['join'] || {})[roomId] || {})['timeline'] || {};
|
||||
const syncedMessages = timeline['events'] || [];
|
||||
token = timeline['prev_batch'] || token;
|
||||
for (const event of syncedMessages) {
|
||||
if (event['sender'] === sender) messages.push(event);
|
||||
if (event['type'] === 'm.room.member' && event['state_key'] === sender) {
|
||||
if (event['content'] && event['content']['membership'] === 'join') {
|
||||
return messages; // we're done!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (token) {
|
||||
const bfMessages = await backfill(token);
|
||||
token = bfMessages['end'];
|
||||
|
||||
let token = timeline['prev_batch'] || response['next_batch'];
|
||||
let bfMessages = {chunk: syncedMessages, end: token};
|
||||
do {
|
||||
for (const event of (bfMessages['chunk'] || [])) {
|
||||
if (event['sender'] === sender) messages.push(event);
|
||||
if (event['type'] === 'm.room.member' && event['state_key'] === sender) {
|
||||
if (event['content'] && event['content']['membership'] === 'join') {
|
||||
return messages; // we're done!
|
||||
}
|
||||
if (processed >= limit) return messages; // we're done even if we don't want to be
|
||||
processed++;
|
||||
|
||||
if (stopProcessingMembers.includes(event['sender'])) continue;
|
||||
if (testUser(event['sender'])) messages.push(event);
|
||||
if (event['type'] === 'm.room.member' && testUser(event['state_key']) && isTrueJoinEvent(event)) {
|
||||
stopProcessingMembers.push(event['sender']);
|
||||
if (!isGlob) return messages; // done!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (token) {
|
||||
bfMessages = await backfill(token);
|
||||
let lastToken = token;
|
||||
token = bfMessages['end'];
|
||||
if (lastToken === token) {
|
||||
LogService.warn("utils", "Backfill returned same end token - returning");
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
} while (token);
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user