1
0
Fork 0

feat(discord): integrate RBAC into Discord bot

Replace legacy role-name checks in isStaff with hasPermission(discord:staff).
Auto-assign the 'user' role document on signup. Import hasPermission in
announce command for future permission gating.
This commit is contained in:
Jason Fraley 2026-08-19 19:48:28 -04:00
parent 1f9f919443
commit d3890cc191
3 changed files with 14 additions and 1 deletions

View file

@ -7,6 +7,7 @@ import {
import type { BotCommand } from "./index"; import type { BotCommand } from "./index";
import { botConfig } from "@/bot/config"; import { botConfig } from "@/bot/config";
import { isStaff } from "@/bot/lib/roles"; import { isStaff } from "@/bot/lib/roles";
import { hasPermission } from "@/utils/access-control/hasPermission";
const ANNOUNCE_COLOR = 0xf59e0b; const ANNOUNCE_COLOR = 0xf59e0b;

View file

@ -2,6 +2,7 @@ import type { GuildMember } from "discord.js";
import type { Payload } from "payload"; import type { Payload } from "payload";
import { botConfig } from "@/bot/config"; import { botConfig } from "@/bot/config";
import { findUserByDiscordId } from "@/bot/lib/resolve"; import { findUserByDiscordId } from "@/bot/lib/resolve";
import { hasPermission } from "@/utils/access-control/hasPermission";
export const isStaff = async (member: GuildMember, payload: Payload): Promise<boolean> => { export const isStaff = async (member: GuildMember, payload: Payload): Promise<boolean> => {
if (member.roles.cache.some((role) => botConfig.staffRoleIds.includes(role.id))) { if (member.roles.cache.some((role) => botConfig.staffRoleIds.includes(role.id))) {
@ -9,5 +10,5 @@ export const isStaff = async (member: GuildMember, payload: Payload): Promise<bo
} }
const user = await findUserByDiscordId(payload, member.id); const user = await findUserByDiscordId(payload, member.id);
if (!user) return false; if (!user) return false;
return (user.roles ?? []).some((role) => role === "admin" || role === "developer"); return await hasPermission(payload, user, "discord:staff");
}; };

View file

@ -48,6 +48,16 @@ export const createDiscordUser = async (
input: SignupInput, input: SignupInput,
): Promise<{ user: User; tempPassword: string }> => { ): Promise<{ user: User; tempPassword: string }> => {
const tempPassword = generateTempPassword(); const tempPassword = generateTempPassword();
const userRole = await payload.find({
collection: "roles",
where: { slug: { equals: "user" } },
limit: 1,
depth: 0,
overrideAccess: true,
});
const userRoleId = userRole.docs[0]?.id;
const user = await payload.create({ const user = await payload.create({
collection: "users", collection: "users",
data: { data: {
@ -57,6 +67,7 @@ export const createDiscordUser = async (
displayName: input.displayName, displayName: input.displayName,
steamId: input.steamId, steamId: input.steamId,
roles: ["user"], roles: ["user"],
roleDocs: userRoleId ? [userRoleId] : [],
password: tempPassword, password: tempPassword,
}, },
overrideAccess: true, overrideAccess: true,