fix(permissions): gate role hierarchy on known membership (#2370)

This commit is contained in:
Hampus
2026-09-02 17:29:06 +02:00
committed by GitHub
parent 1598f48edd
commit 8ebc9400ce
38 changed files with 68 additions and 52 deletions
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "نوع رسالة غير معروف"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "إذن غير معروف"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Неизвестен тип съобщение"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Неизвестно разрешение"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Neznámý typ zprávy"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Neznámé oprávnění"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Ukendt meddelelsestype"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Ukendt tilladelse"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Unbekannter Nachrichtentyp"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Unbekannte Berechtigung"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Άγνωστος τύπος μηνύματος"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Άγνωστη άδεια"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Unknown message type"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Unknown permission"
@@ -33878,7 +33878,7 @@ msgid "Unknown message type"
msgstr "Unknown message type"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Unknown permission"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Tipo de mensaje desconocido"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Permiso desconocido"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Tipo de mensaje desconocido"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Permiso desconocido"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Tuntematon viestityyppi"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Tuntematon käyttöoikeus"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Type de message inconnu"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Permission inconnue"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "סוג הודעה לא ידוע"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "הרשאה לא ידועה"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "मैसेज का प्रकार अज्ञात है"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "अज्ञात अनुमति"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Nepoznata vrsta poruke"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Nepoznata dozvola"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Ismeretlen üzenettípus"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Ismeretlen engedély"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Jenis pesan tidak diketahui"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Izin tidak dikenal"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Tipo di messaggio sconosciuto"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Permesso sconosciuto"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "不明なメッセージタイプ"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "不明な権限"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "알 수 없는 메시지 유형"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "알 수 없는 권한"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Nežinomas pranešimo tipas"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Nežinomas leidimas"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Onbekend berichttype"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Onbekende machtiging"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Ukjent meldingstype"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Ukjent tillatelse"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Nieznany typ wiadomości"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Nieznane uprawnienie"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Tipo de mensagem desconhecido"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Permissão desconhecida"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Tip de mesaj necunoscut"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Permisiune necunoscută"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Неизвестный тип сообщения"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Неизвестное разрешение"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Okänd meddelandetyp"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Okänd behörighet"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "ประเภทข้อความไม่รู้จัก"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "สิทธิ์ที่ไม่รู้จัก"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Bilinmeyen mesaj türü"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Bilinmeyen izin"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Невідомий тип повідомлення"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Невідомий дозвіл"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "Loại tin nhắn không xác định"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "Quyền không xác định"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "未知消息类型"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "未知权限"
@@ -33877,7 +33877,7 @@ msgid "Unknown message type"
msgstr "不明訊息類型"
#. Fallback label for a permission bit the client does not recognize.
#: src/features/permissions/utils/PermissionUtils.ts:410
#: src/features/permissions/utils/PermissionUtils.ts:421
msgid "Unknown permission"
msgstr "不明權限"
@@ -109,6 +109,16 @@ class GuildMembers {
return this.members[guildId]?.[userId] ?? null;
}
isMembershipKnown(guildId: string, userId?: string | null): boolean {
if (!userId) {
return false;
}
if (this.members[guildId]?.[userId]) {
return true;
}
return this.nonMembers[guildId]?.has(userId) ?? false;
}
isUserTimedOut(guildId: string | null, userId?: string | null): boolean {
return this.getCommunicationDisabledUntil(guildId, userId) !== null;
}
@@ -155,6 +165,7 @@ class GuildMembers {
if (!this.members[guild.id]) {
this.members[guild.id] = {};
}
delete this.nonMembers[guild.id];
const members = this.members[guild.id];
cacheGuildMemberUsers(guild.members);
for (const member of guild.members) {
@@ -205,6 +216,7 @@ class GuildMembers {
}
handleMemberRemove(guildId: string, userId: string): void {
this.markAsNonMember(guildId, userId);
const existingMembers = this.members[guildId];
if (!existingMembers) {
return;
@@ -277,22 +289,18 @@ class GuildMembers {
return;
}
const returnedIds = new Set(pending.members.map((record) => record.user.id));
const notFound: Array<string> = [];
for (const id of requested) {
if (!returnedIds.has(id)) {
notFound.push(id);
this.markAsNonMember(pending.guildId, id);
}
}
if (notFound.length === 0) {
return;
}
if (!this.nonMembers[pending.guildId]) {
this.nonMembers[pending.guildId] = new Set();
}
const cache = this.nonMembers[pending.guildId];
for (const id of notFound) {
cache.add(id);
}
private markAsNonMember(guildId: string, userId: string): void {
if (!this.nonMembers[guildId]) {
this.nonMembers[guildId] = new Set();
}
this.nonMembers[guildId].add(userId);
}
async fetchMembers(
@@ -462,7 +470,7 @@ class GuildMembers {
}
const generation = this.messageMemberRequestGeneration;
try {
await this.fetchMembers(guildId, {userIds, markMissingAsNonMembers: false});
await this.fetchMembers(guildId, {userIds, markMissingAsNonMembers: true});
if (generation === this.messageMemberRequestGeneration) {
this.forgetPendingMessageMembers(guildId, userIds);
}
@@ -25,9 +25,7 @@ export function useRoleHierarchy(guild: Guild | null | undefined) {
if (!guild || !currentUser) return false;
if (guild.isOwner(currentUser.id)) return true;
if (guild.isOwner(targetUserId)) return false;
const wireGuild = guild.toJSON();
const targetHighestRole = PermissionUtils.getHighestRole(wireGuild, targetUserId);
return PermissionUtils.isRoleHigher(wireGuild, currentUser.id, currentUserHighestRole, targetHighestRole);
return PermissionUtils.canManageTargetUser(guild.toJSON(), currentUser.id, currentUserHighestRole, targetUserId);
},
[guild, currentUser, currentUserHighestRole],
);
@@ -82,8 +82,7 @@ class Permission {
}
const wireGuild = guild.toJSON();
const myHighestRole = PermissionUtils.getHighestRole(wireGuild, me.id);
const otherHighestRole = PermissionUtils.getHighestRole(wireGuild, otherUserId);
return PermissionUtils.isRoleHigher(wireGuild, me.id, myHighestRole, otherHighestRole);
return PermissionUtils.canManageTargetUser(wireGuild, me.id, myHighestRole, otherUserId);
}
handleGatewayReady(): void {
@@ -33,7 +33,7 @@ interface PermissionOverwrite {
deny: bigint;
}
interface Role {
export interface Role {
id: string;
permissions: bigint;
position: number;
@@ -192,6 +192,17 @@ export function getHighestRole(guild: Guild, userId: string): Role | null {
return memberRoles[0] ?? null;
}
export function canManageTargetUser(
guild: Guild,
userId: string,
userHighestRole: Role | null,
targetUserId: string,
): boolean {
if (guild.owner_id === userId) return true;
if (!GuildMembers.isMembershipKnown(guild.id, targetUserId)) return false;
return isRoleHigher(guild, userId, userHighestRole, getHighestRole(guild, targetUserId));
}
export function can(
permission: bigint,
user: