Skip to content

Conversation

@Rufat00
Copy link
Contributor

@Rufat00 Rufat00 commented Oct 30, 2025

Why

The previous role and permissions system was dangerous and unscalable

What

  • Adds separate roles table
  • New smart permissions system
  • New admin section to create and manage roles
  • Introduced getCurrentUser helper to make process of getting user info easier

Satisfies

https://linear.app/acmutsa/issue/HK-201/revamps-permission-system-for-hackkit
resolves #198

image image image

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a comprehensive role-based access control (RBAC) system with granular permissions, user banning functionality, and various improvements. The old hardcoded role enum is replaced with a dynamic database-backed roles system with a permissions bitmask architecture.

  • Replaces hardcoded roles with a database-backed roles system using permission bitmasks
  • Adds user banning/suspension functionality with ban tracking
  • Implements permission-based access control across admin features
  • Removes deprecated backup app dependencies from pnpm-lock.yaml

Reviewed Changes

Copilot reviewed 56 out of 58 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
pnpm-lock.yaml Removes unused backup app dependencies and deprecated package entries
packages/db/schema.ts Adds roles and bannedUsers tables, converts role field to role_id foreign key
packages/db/types.ts Adds UserWithRole type including role relation
packages/db/functions/*.ts Updates queries to include role relations
apps/web/src/lib/constants/permission.ts Defines PermissionType enum with bitwise flags
apps/web/src/lib/utils/shared/permission.ts Implements PermissionMask class for permission management
apps/web/src/lib/utils/server/admin.ts Refactors admin checks to use permission-based system
apps/web/src/components/admin/roles/* Adds role management UI components
apps/web/src/components/admin/users/BanUserDialog.tsx Adds user banning dialog
apps/web/src/components/Restricted.tsx Permission-based component visibility wrapper
apps/web/src/middleware.ts Adds ban check middleware
apps/web/src/actions/admin/*.ts Updates actions with permission checks
apps/web/src/app/admin/**/*.tsx Updates admin pages with permission-based guards
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +92 to +94
<Badge>{currentRoleName}</Badge>
<span>&rarr;</span>
<Badge>
{titleCase(roleToSet.replace("_", " "))}
</Badge>
<Badge>{currentRoleName}</Badge>
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The target role badge displays currentRoleName instead of the new role name. Line 94 should display the name of the role being changed to (roleToSet), not the current role.

Copilot uses AI. Check for mistakes.
<DialogHeader>
<DialogTitle>Ban {name}.</DialogTitle>
<DialogDescription>
Ban this user (not permament action).
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'permament' to 'permanent'.

Suggested change
Ban this user (not permament action).
Ban this user (not permanent action).

Copilot uses AI. Check for mistakes.
const { execute } = useAction(removeUserBan, {
async onSuccess() {
toast.dismiss();
toast.success("Suspension successfuly removed!");
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'successfuly' to 'successfully'.

Copilot uses AI. Check for mistakes.
},
async onError(e) {
toast.dismiss();
toast.error("An error occurred while removing suspenssion.");
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'suspenssion' to 'suspension'.

Copilot uses AI. Check for mistakes.
{!!banInstance && (
<div className="absolute left-0 top-28 w-screen bg-destructive p-2 text-center">
<strong>
This user has been suspended, reason for suspenssion:{" "}
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'suspenssion' to 'suspension'.

Suggested change
This user has been suspended, reason for suspenssion:{" "}
This user has been suspended, reason for suspension:{" "}

Copilot uses AI. Check for mistakes.
Comment on lines 69 to 78
const canDeleteRole = (() => {
try {
return (
userHasPermission(currentUser, PermissionType.DELETE_ROLES) &&
compareUserPosition(currentUser, role.position, "higher")
);
} catch (e) {
return false;
}
})();
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused variable canDeleteRole.

Suggested change
const canDeleteRole = (() => {
try {
return (
userHasPermission(currentUser, PermissionType.DELETE_ROLES) &&
compareUserPosition(currentUser, role.position, "higher")
);
} catch (e) {
return false;
}
})();

Copilot uses AI. Check for mistakes.
Comment on lines 1 to 17
import {
Body,
Button,
Container,
Column,
Head,
Heading,
Hr,
Html,
Img,
Link,
Preview,
Row,
Section,
Tailwind,
Text,
} from "@react-email/components";
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused imports Button, Column, Head, Hr, Html, Link, Preview, Row.

Copilot uses AI. Check for mistakes.
@@ -1,18 +1,24 @@
import { db, eq } from "..";
import { userCommonData, userHackerData } from "../schema";
import { SQLiteRelationalQuery } from "drizzle-orm/sqlite-core/query-builders/query";
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import SQLiteRelationalQuery.

Copilot uses AI. Check for mistakes.
import { db, eq } from "..";
import { userCommonData, userHackerData } from "../schema";
import { SQLiteRelationalQuery } from "drizzle-orm/sqlite-core/query-builders/query";
import { db, eq, InferSelectModel } from "..";
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import InferSelectModel.

Copilot uses AI. Check for mistakes.
import { userCommonData, userHackerData } from "../schema";
import { SQLiteRelationalQuery } from "drizzle-orm/sqlite-core/query-builders/query";
import { db, eq, InferSelectModel } from "..";
import { roles, userCommonData, userHackerData } from "../schema";
Copy link

Copilot AI Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import roles.

Copilot uses AI. Check for mistakes.
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Nov 1, 2025

Deploying hackkit with  Cloudflare Pages  Cloudflare Pages

Latest commit: f5f2a1b
Status: ✅  Deploy successful!
Preview URL: https://8c961bbf.hackkit.pages.dev
Branch Preview URL: https://permissions-refactored.hackkit.pages.dev

View logs

@joshuasilva414
Copy link
Contributor

Screenshot 2025-11-02 at 3 51 52 PM New user registration does not seem to be working

Copy link
Contributor

@joshuasilva414 joshuasilva414 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some concerns about this use case I found where a role can move themselves up above other roles and then change the lower roles permissions if they have the right boxes checked.

I'm also curious about this disable checkbox. Why can't I turn off this permission, but I can turn off all the other ones?

Image

@Rufat00 Rufat00 assigned Rufat00 and unassigned Rufat00 Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create New Role and Permissions System

3 participants