fix(api): Disallow banning nonexistent users (#1061)

This commit is contained in:
PilkeySEK authored and GitHub committed 2026-06-19 22:15:33 +01:00
1 parent b450a4ee93
commit e712f9691d
2 files changed
+25 -3

No files matched your search

@@ -8,6 +8,7 @@ import {MissingPermissionsError} from '@fluxer/errors/src/domains/core/MissingPe
import {BannedFromGuildError} from '@fluxer/errors/src/domains/guild/BannedFromGuildError'; import {BannedFromGuildError} from '@fluxer/errors/src/domains/guild/BannedFromGuildError';
import {IpBannedFromGuildError} from '@fluxer/errors/src/domains/guild/IpBannedFromGuildError'; import {IpBannedFromGuildError} from '@fluxer/errors/src/domains/guild/IpBannedFromGuildError';
import {UnknownGuildMemberError} from '@fluxer/errors/src/domains/guild/UnknownGuildMemberError'; import {UnknownGuildMemberError} from '@fluxer/errors/src/domains/guild/UnknownGuildMemberError';
import {UnknownUserError} from '@fluxer/errors/src/domains/user/UnknownUserError';
import {isSameIpDecisionMatch} from '@fluxer/ip_utils/src/IpAddress'; import {isSameIpDecisionMatch} from '@fluxer/ip_utils/src/IpAddress';
import type {GuildBanResponse} from '@fluxer/schema/src/domains/guild/GuildMemberSchemas'; import type {GuildBanResponse} from '@fluxer/schema/src/domains/guild/GuildMemberSchemas';
import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService'; import type {IpInfoService} from '@pkgs/geoip/src/IpInfoService';
@@ -62,6 +63,10 @@ export class GuildModerationService {
}); });
if (!hasPermission) throw new MissingPermissionsError(); if (!hasPermission) throw new MissingPermissionsError();
if (userId === targetId) throw new UnknownGuildMemberError(); if (userId === targetId) throw new UnknownGuildMemberError();
const targetUser = await this.userRepository.findUnique(targetId);
if (!targetUser) {
throw new UnknownUserError();
}
const targetMember = await this.guildRepository.getMember(guildId, targetId); const targetMember = await this.guildRepository.getMember(guildId, targetId);
if (targetMember) { if (targetMember) {
const canManage = await this.gatewayService.checkTargetMember({guildId, userId, targetUserId: targetId}); const canManage = await this.gatewayService.checkTargetMember({guildId, userId, targetUserId: targetId});
@@ -74,9 +79,8 @@ export class GuildModerationService {
days: deleteMessageDays, days: deleteMessageDays,
}); });
} }
const targetUser = await this.userRepository.findUnique(targetId); const targetIp = targetUser.lastActiveIp || null;
const targetIp = targetUser?.lastActiveIp || null; const targetEmail = targetUser.email?.toLowerCase() || null;
const targetEmail = targetUser?.email?.toLowerCase() || null;
let expiresAt: Date | null = null; let expiresAt: Date | null = null;
if (banDurationSeconds && banDurationSeconds > 0) { if (banDurationSeconds && banDurationSeconds > 0) {
expiresAt = new Date(Date.now() + banDurationSeconds * 1000); expiresAt = new Date(Date.now() + banDurationSeconds * 1000);
@@ -186,6 +186,24 @@ describe('Guild Member Management', () => {
.expect(HTTP_STATUS.NO_CONTENT) .expect(HTTP_STATUS.NO_CONTENT)
.execute(); .execute();
}); });
test('should ban non-member from guild', async () => {
const {owner, guild} = await setupTestGuildWithMembers(harness, 1);
const nonMember = await createTestAccount(harness);
await createBuilder(harness, owner.token)
.put(`/guilds/${guild.id}/bans/${nonMember.userId}`)
.body({})
.expect(HTTP_STATUS.NO_CONTENT)
.execute();
});
test('should disallow banning nonexistent user from guild', async () => {
const {owner, guild} = await setupTestGuildWithMembers(harness, 1);
const nonExistentId = '1234567890123456789';
await createBuilder(harness, owner.token)
.put(`/guilds/${guild.id}/bans/${nonExistentId}`)
.body({})
.expect(HTTP_STATUS.NOT_FOUND)
.execute();
});
test('should fall back to audit log reason header when ban reason is omitted', async () => { test('should fall back to audit log reason header when ban reason is omitted', async () => {
const {owner, members, guild} = await setupTestGuildWithMembers(harness, 1); const {owner, members, guild} = await setupTestGuildWithMembers(harness, 1);
const member = members[0]; const member = members[0];