better-auth
Version:
The most comprehensive authentication framework for TypeScript.
33 lines (32 loc) • 1.56 kB
JavaScript
import { APIError } from "../../api/index.mjs";
import { defaultRoles } from "./access/statement.mjs";
import { cacheAllRoles, hasPermissionFn } from "./permission.mjs";
import * as z from "zod";
//#region src/plugins/organization/has-permission.ts
const hasPermission = async (input, ctx) => {
let acRoles = { ...input.options.roles || defaultRoles };
if (ctx && input.organizationId && input.options.dynamicAccessControl?.enabled && input.options.ac && !input.useMemoryCache) {
const roles = await ctx.context.adapter.findMany({
model: "organizationRole",
where: [{
field: "organizationId",
value: input.organizationId
}]
});
for (const { role, permission: permissionsString } of roles) {
const result = z.record(z.string(), z.array(z.string())).safeParse(JSON.parse(permissionsString));
if (!result.success) {
ctx.context.logger.error("[hasPermission] Invalid permissions for role " + role, { permissions: JSON.parse(permissionsString) });
throw new APIError("INTERNAL_SERVER_ERROR", { message: "Invalid permissions for role " + role });
}
const merged = { ...acRoles[role]?.statements };
for (const [key, actions] of Object.entries(result.data)) merged[key] = [.../* @__PURE__ */ new Set([...merged[key] ?? [], ...actions])];
acRoles[role] = input.options.ac.newRole(merged);
}
}
if (input.useMemoryCache) acRoles = cacheAllRoles.get(input.organizationId) || acRoles;
cacheAllRoles.set(input.organizationId, acRoles);
return hasPermissionFn(input, acRoles);
};
//#endregion
export { hasPermission };