sendou.ink/app/modules/permissions/guards.server.ts
Kalle d2551d2706
Some checks failed
Tests and checks on push / run-checks-and-tests (push) Has been cancelled
Updates translation progress / update-translation-progress-issue (push) Has been cancelled
Global roles refactor (#2212)
* Initial

* isMod etc.

* canPerformAdminActions

* isAdmin

* isSupporter

* admin override

* Lohi

* Badge manage with new permissions style

* Refactor badge loading logic

* Move funcs

* Delete permissions.ts

* DRY
2025-04-21 23:51:30 +03:00

39 lines
1.2 KiB
TypeScript

import type { EntityWithPermissions, Role } from "~/modules/permissions/types";
import { isAdmin } from "./utils";
// TODO: could avoid passing user in after remix middlewares land with async context
/**
* Checks if a user has the required global role.
*
* @throws {Response} - Throws a 403 Forbidden response if the user does not have the required role.
*/
export function requireRole(user: { roles: Array<Role> }, role: Role) {
if (!user.roles.includes(role)) {
throw new Response("Forbidden", { status: 403 });
}
}
/**
* Checks if a user has the required permission to perform an action on a given entity.
*
* @throws {Response} - Throws a 403 Forbidden response if the user does not have the required permission.
*/
export function requirePermission<
T extends EntityWithPermissions,
K extends keyof T["permissions"],
>(obj: T, permission: K, user: { id: number }) {
// admin can do anything in production but not in development for better testing
if (process.env.NODE_ENV === "production" && isAdmin(user)) {
return;
}
const permissions = obj.permissions as Record<K, number[]>;
if (permissions[permission].includes(user.id)) {
return;
}
throw new Response("Forbidden", { status: 403 });
}