prisma-extension-casl
Version:
Enforce casl abilities on prisma client
126 lines (120 loc) • 4.96 kB
text/typescript
import * as _prisma_client_runtime_library from '@prisma/client/runtime/library';
import { PureAbility, AbilityTuple, AbilityBuilder } from '@casl/ability';
import { PrismaQuery } from '@casl/prisma';
import { Prisma } from '@prisma/client';
type CreationTree = {
action: string;
model: Prisma.ModelName;
children: Record<string, CreationTree>;
/**
* mutation query for creation / update
* with fields that are modified on mutation
* and the where query
*
* we use the where query to see which entries have been modified
* and the check accessibleBy per field
* to see if mutations are forbidden
*/
mutation: {
fields: string[];
where: any;
}[];
};
type PrismaExtensionCaslOptions = {
/**
* will add a field on each returned prisma result that stores allowed actions on result (not nested)
* so instead of { id: 0 } it would return { id: 0, [permissionField]: ['create', 'read', 'update', 'delete'] }
*
* to return other actions, please use addPermissionActions
*/
permissionField?: string;
/**
* adds additional permission actions to ['create', 'read', 'update', 'delete']
* that should be returned if permissionField is used.
*/
addPermissionActions?: string[];
/** uses transaction to allow using client queries before actual query, if fails, whole query will be rolled back */
beforeQuery?: (tx: Prisma.TransactionClient) => Promise<void>;
/** uses transaction to allow using client queries after actual query, if fails, whole query will be rolled back */
afterQuery?: (tx: Prisma.TransactionClient) => Promise<void>;
/** max wait for batch transaction - default 30000 */
txMaxWait?: number;
/** timeout for batch transaction - default 30000 */
txTimeout?: number;
};
type PrismaCaslOperation = 'create' | 'createMany' | 'createManyAndReturn' | 'upsert' | 'findFirst' | 'findFirstOrThrow' | 'findMany' | 'findUnique' | 'findUniqueOrThrow' | 'aggregate' | 'count' | 'groupBy' | 'update' | 'updateMany' | 'updateManyAndReturn' | 'delete' | 'deleteMany';
/**
* Applies CASL authorization logic to prisma query
*
* @param operation Prisma Operation `findUnique` etc
* @param args Prisma query
* @param abilities Casl prisma abilities
* @param model Prisma model
* @returns Enriched query with casl authorization
*/
declare function applyCaslToQuery(operation: PrismaCaslOperation, args: any, abilities: PureAbility<AbilityTuple, PrismaQuery>, model: Prisma.ModelName, queryAllRuleRelations?: boolean): {
creationTree: CreationTree | undefined;
args: any;
mask: Record<string, any>;
} | {
args: any;
mask: undefined;
creationTree: CreationTree | undefined;
};
/**
* enrich a prisma client to check for CASL abilities even in nested queries
*
* `client.$extends(useCaslAbilities(build))`
*
* https://casl.js.org/v6/en/package/casl-prisma
*
*
* @param getAbilities function to return CASL prisma abilities
* - this is a function call to instantiate abilities on each prisma query to allow adding i.e. context or claims
* @returns enriched prisma client
*/
/**
* enrich a prisma client to check for CASL abilities even in nested queries
*
* `client.$extends(useCaslAbilities(build))`
*
* https://casl.js.org/v6/en/package/casl-prisma
*
*
* @param getAbilityFactory function to return CASL prisma abilities
* - this is a function call to instantiate abilities on each prisma query to allow adding i.e. context or claims
* @param opts additional options: { permissionField, additionalActions }
* @returns enriched prisma client
* @returns
*/
declare function useCaslAbilities(getAbilityFactory: () => AbilityBuilder<PureAbility<AbilityTuple, PrismaQuery>>, opts?: PrismaExtensionCaslOptions): (client: any) => {
$extends: {
extArgs: {
result: {};
model: {};
query: {};
client: {
$casl: () => (extendFactory: (factory: AbilityBuilder<PureAbility<AbilityTuple, PrismaQuery>>) => AbilityBuilder<PureAbility<AbilityTuple, PrismaQuery>>) => _prisma_client_runtime_library.DynamicClientExtensionThis<Prisma.TypeMap<_prisma_client_runtime_library.InternalArgs & {
result: {};
model: {};
query: {};
client: {};
}, {}>, Prisma.TypeMapCb<{}>, {
result: {};
model: {};
query: {};
client: {};
}>;
};
};
};
};
/**
* recreates getBatchId from prisma
* //https://github.com/prisma/prisma/blob/1a9ef0fbd3948ee708add6816a33743e1ff7df9c/packages/client/src/runtime/core/jsonProtocol/getBatchId.ts#L4
*
* @param query
* @returns
*/
declare function getBatchId(query: any): string | undefined;
export { applyCaslToQuery, getBatchId, useCaslAbilities };