Add proper permission check
This commit is contained in:
parent
c044f50b19
commit
152d444067
|
|
@ -73,6 +73,8 @@ export async function getUserFromToken(token: string) {
|
||||||
const user = await prisma.user.findFirst({
|
const user = await prisma.user.findFirst({
|
||||||
include:{
|
include:{
|
||||||
photoProfile: true,
|
photoProfile: true,
|
||||||
|
roles: true,
|
||||||
|
directPermissions: true
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
id: decodedToken.id,
|
id: decodedToken.id,
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,31 @@
|
||||||
import { getUserFromToken } from "../authUtils";
|
import checkPermission from "./checkPermission";
|
||||||
import getCurrentUser from "./getCurrentUser";
|
import getCurrentUser from "./getCurrentUser";
|
||||||
|
|
||||||
type PermissionsInput = Record<string, string>;
|
|
||||||
|
|
||||||
type PermissionsOutput = Record<string, boolean>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks multiple permissions for the current user and returns an object indicating
|
* Checks multiple permissions for the current user and returns an object indicating
|
||||||
* whether each permission is granted.
|
* whether each permission is granted.
|
||||||
*
|
*
|
||||||
* @param {PermissionsInput} permissions - An object with keys as permission names and values as the required roles/permissions.
|
* @param permissions - An object with keys as permission names and values as the required roles/permissions.
|
||||||
* @returns {Promise<PermissionsOutput>} An object with keys as permission names and boolean values indicating whether the permission is granted.
|
* @returns An object with keys as permission names and boolean values indicating whether the permission is granted.
|
||||||
*/
|
*/
|
||||||
async function checkMultiplePermissions<T extends Record<string, string>>(permissions: T): Promise<{ [K in keyof T]: boolean }> {
|
async function checkMultiplePermissions<T extends Record<string, string>>(
|
||||||
const permissionResults: Partial<{ [K in keyof T]: boolean }> = {};
|
permissions: T
|
||||||
const currentUser = await getCurrentUser();
|
): Promise<{ [K in keyof T]: boolean }> {
|
||||||
|
const permissionResults: Partial<{ [K in keyof T]: boolean }> = {};
|
||||||
|
const currentUser = await getCurrentUser();
|
||||||
|
|
||||||
for (const permissionKey in permissions) {
|
for (const permissionKey in permissions) {
|
||||||
if (permissions.hasOwnProperty(permissionKey)) {
|
if (permissions.hasOwnProperty(permissionKey)) {
|
||||||
const requiredPermission = permissions[permissionKey];
|
const requiredPermission = permissions[permissionKey];
|
||||||
// const isPermissionGranted: boolean = currentUser ? currentUser.roles.includes(requiredPermission) : false;
|
const isPermissionGranted = await checkPermission(
|
||||||
const isPermissionGranted = true;
|
requiredPermission,
|
||||||
permissionResults[permissionKey] = isPermissionGranted;
|
currentUser
|
||||||
}
|
);
|
||||||
}
|
permissionResults[permissionKey] = isPermissionGranted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return permissionResults as { [K in keyof T]: boolean };
|
return permissionResults as { [K in keyof T]: boolean };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default checkMultiplePermissions;
|
export default checkMultiplePermissions;
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,42 @@
|
||||||
import { cookies } from "next/headers"
|
|
||||||
import "server-only"
|
|
||||||
import { getUserFromToken } from "../authUtils";
|
|
||||||
import getCurrentUser from "./getCurrentUser";
|
import getCurrentUser from "./getCurrentUser";
|
||||||
|
import "server-only";
|
||||||
|
|
||||||
export default async function checkPermission(permission?: "guest-only" | "authenticated-only" | string & {}){
|
/**
|
||||||
//TODO: Add permission check
|
* Checks if the current user has the specified permissions.
|
||||||
|
*
|
||||||
|
* @param permission - The specific permission to check. If it's "guest-only", the function returns true if the user is not authenticated. If it's "authenticated-only", it returns true if the user is authenticated. For other permissions, it checks against the user's roles and direct permissions.
|
||||||
|
* @param currentUser - Optional. The current user object. If not provided, the function retrieves the current user.
|
||||||
|
* @returns true if the user has the required permission, otherwise false.
|
||||||
|
*/
|
||||||
|
export default async function checkPermission(
|
||||||
|
permission?: "guest-only" | "authenticated-only" | (string & {}),
|
||||||
|
currentUser?: Awaited<ReturnType<typeof getCurrentUser>>
|
||||||
|
): Promise<boolean> {
|
||||||
|
// Allow if no specific permission is required.
|
||||||
|
if (!permission) return true;
|
||||||
|
|
||||||
|
// Retrieve current user if not provided.
|
||||||
|
const user = currentUser ?? (await getCurrentUser());
|
||||||
|
|
||||||
if (!permission) return true; //allow if no permission supplied
|
// Handle non-authenticated users.
|
||||||
|
if (!user) {
|
||||||
|
return permission === "guest-only";
|
||||||
|
}
|
||||||
|
|
||||||
const user = await getCurrentUser()
|
// Allow authenticated users if the permission is 'authenticated-only'.
|
||||||
|
if (permission === "authenticated-only") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!user && permission === "guest-only"){
|
// Short-circuit for super-admin role to allow all permissions.
|
||||||
return true;
|
if (user.roles.some((role) => role.code === "super-admin")) return true;
|
||||||
}
|
|
||||||
|
|
||||||
if (user && permission === "authenticated-only"){
|
// Aggregate all role codes and direct permissions into a set for efficient lookup.
|
||||||
return true;
|
const permissions = new Set<string>([
|
||||||
}
|
...user.roles.map((role) => role.code),
|
||||||
|
...user.directPermissions.map((dp) => dp.code),
|
||||||
|
]);
|
||||||
|
|
||||||
return true;
|
// Check if the user has the required permission.
|
||||||
}
|
return permissions.has(permission);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user