fix(moderation): policy list viewer reads legacy Draupnir/Mjolnir rule types
Only the stable m.policy.rule.* types were queried, so lists still writing org.matrix.mjolnir.rule.* showed as empty. Query both and de-duplicate by entity+recommendation. Fixes #22 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -24,6 +24,14 @@ const POLICY_USER_EVENT = 'm.policy.rule.user';
|
|||||||
const POLICY_ROOM_EVENT = 'm.policy.rule.room';
|
const POLICY_ROOM_EVENT = 'm.policy.rule.room';
|
||||||
const POLICY_SERVER_EVENT = 'm.policy.rule.server';
|
const POLICY_SERVER_EVENT = 'm.policy.rule.server';
|
||||||
|
|
||||||
|
// Legacy, unstable-prefixed event types still emitted by Draupnir/Mjolnir
|
||||||
|
// policy lists that predate MSC stabilization (or haven't migrated). Queried
|
||||||
|
// alongside the stable types and merged/de-duped so those lists don't show
|
||||||
|
// as falsely empty.
|
||||||
|
const LEGACY_POLICY_USER_EVENT = 'org.matrix.mjolnir.rule.user';
|
||||||
|
const LEGACY_POLICY_ROOM_EVENT = 'org.matrix.mjolnir.rule.room';
|
||||||
|
const LEGACY_POLICY_SERVER_EVENT = 'org.matrix.mjolnir.rule.server';
|
||||||
|
|
||||||
type PolicyRuleContent = {
|
type PolicyRuleContent = {
|
||||||
entity?: string;
|
entity?: string;
|
||||||
reason?: string;
|
reason?: string;
|
||||||
@@ -76,6 +84,23 @@ function extractPolicyEntries(events: MatrixEvent[]): PolicyEntry[] {
|
|||||||
.filter((entry) => entry.entity !== '');
|
.filter((entry) => entry.entity !== '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge policy entries from the stable and legacy event types for a rule
|
||||||
|
* kind, de-duplicating by entity+recommendation so a room that emits both a
|
||||||
|
* stable and a legacy rule for the same target isn't double-listed.
|
||||||
|
*/
|
||||||
|
export function dedupePolicyEntries(entries: PolicyEntry[]): PolicyEntry[] {
|
||||||
|
const seen = new Set<string>();
|
||||||
|
const result: PolicyEntry[] = [];
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
const key = `${entry.entity} ${entry.recommendation}`;
|
||||||
|
if (seen.has(key)) return;
|
||||||
|
seen.add(key);
|
||||||
|
result.push(entry);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// ── Entry row ─────────────────────────────────────────────────────────────────
|
// ── Entry row ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
function PolicyEntryRow({ entry }: { entry: PolicyEntry }) {
|
function PolicyEntryRow({ entry }: { entry: PolicyEntry }) {
|
||||||
@@ -201,9 +226,24 @@ export function PolicyListViewer({ requestClose }: PolicyListViewerProps) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setUserEntries(extractPolicyEntries(getRoomPolicyEvents(room, POLICY_USER_EVENT)));
|
setUserEntries(
|
||||||
setRoomEntries(extractPolicyEntries(getRoomPolicyEvents(room, POLICY_ROOM_EVENT)));
|
dedupePolicyEntries([
|
||||||
setServerEntries(extractPolicyEntries(getRoomPolicyEvents(room, POLICY_SERVER_EVENT)));
|
...extractPolicyEntries(getRoomPolicyEvents(room, POLICY_USER_EVENT)),
|
||||||
|
...extractPolicyEntries(getRoomPolicyEvents(room, LEGACY_POLICY_USER_EVENT)),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
setRoomEntries(
|
||||||
|
dedupePolicyEntries([
|
||||||
|
...extractPolicyEntries(getRoomPolicyEvents(room, POLICY_ROOM_EVENT)),
|
||||||
|
...extractPolicyEntries(getRoomPolicyEvents(room, LEGACY_POLICY_ROOM_EVENT)),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
setServerEntries(
|
||||||
|
dedupePolicyEntries([
|
||||||
|
...extractPolicyEntries(getRoomPolicyEvents(room, POLICY_SERVER_EVENT)),
|
||||||
|
...extractPolicyEntries(getRoomPolicyEvents(room, LEGACY_POLICY_SERVER_EVENT)),
|
||||||
|
]),
|
||||||
|
);
|
||||||
setLoadedRoomId(roomId);
|
setLoadedRoomId(roomId);
|
||||||
setError(undefined);
|
setError(undefined);
|
||||||
}, [mx, roomIdInput]);
|
}, [mx, roomIdInput]);
|
||||||
|
|||||||
Reference in New Issue
Block a user