New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@zenstackhq/runtime

Package Overview
Dependencies
Maintainers
2
Versions
276
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zenstackhq/runtime - npm Package Compare versions

Comparing version 2.0.3 to 2.1.0

enhancements/policy/constraint-solver.d.ts

5

enhancements/delegate.js

@@ -84,2 +84,7 @@ "use strict";

Object.entries(where).forEach(([field, value]) => {
if (['AND', 'OR', 'NOT'].includes(field)) {
// recurse into logical group
(0, cross_1.enumerate)(value).forEach((item) => this.injectWhereHierarchy(model, item));
return;
}
const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, field);

@@ -86,0 +91,0 @@ if (!(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom)) {

14

enhancements/policy/handler.d.ts

@@ -1,4 +0,8 @@

import { type DbClientContract } from '../../types';
import { PolicyCrudKind, type DbClientContract } from '../../types';
import type { EnhancementContext, InternalEnhancementOptions } from '../create-enhancement';
import { PrismaProxyHandler } from '../proxy';
type PermissionCheckArgs = {
operation: PolicyCrudKind;
where?: Record<string, number | string | boolean>;
};
/**

@@ -55,2 +59,9 @@ * Prisma proxy handler for injecting access policy check.

subscribe(args: any): Promise<any>;
/**
* Checks if the given operation is possibly allowed by the policy, without querying the database.
* @param operation The CRUD operation.
* @param fieldValues Extra field value filters to be combined with the policy constraints.
*/
check(args: PermissionCheckArgs): Promise<boolean>;
private doCheck;
private get shouldLogQuery();

@@ -62,1 +73,2 @@ private runPostWriteChecks;

}
export {};
import { ZodError } from 'zod';
import { CrudFailureReason } from '../../constants';
import { CrudContract, DbClientContract, PolicyOperationKind } from '../../types';
import { CrudContract, DbClientContract, PolicyCrudKind, PolicyOperationKind } from '../../types';
import type { EnhancementContext, InternalEnhancementOptions } from '../create-enhancement';
import { QueryUtils } from '../query-utils';
import type { CheckerFunc } from '../types';
/**

@@ -83,2 +84,7 @@ * Access policy enforcement utilities

/**
* Gets checker constraints for the given model and operation.
*/
getCheckerConstraint(model: string, operation: PolicyCrudKind): ReturnType<CheckerFunc> | boolean;
private getModelChecker;
/**
* Gets unique constraints for the given model.

@@ -85,0 +91,0 @@ */

@@ -36,3 +36,3 @@ "use strict";

//#endregion
//# Auth guard
//#region Auth guard
this.FULLY_OPEN_AUTH_GUARD = {

@@ -244,3 +244,3 @@ create: true,

if (!provider) {
throw this.unknownError(`zenstack: unable to load authorization guard for ${model}`);
throw this.unknownError(`unable to load authorization guard for ${model}`);
}

@@ -486,3 +486,36 @@ const r = provider({ user: this.user, preValue }, db);

}
//#endregion
//#region Checker
/**
* Gets checker constraints for the given model and operation.
*/
getCheckerConstraint(model, operation) {
const checker = this.getModelChecker(model);
const provider = checker[operation];
if (typeof provider === 'boolean') {
return provider;
}
if (typeof provider !== 'function') {
throw this.unknownError(`invalid ${operation} checker function for ${model}`);
}
// call checker function
return provider({ user: this.user });
}
getModelChecker(model) {
var _a;
if (this.options.kinds && !this.options.kinds.includes('policy')) {
// policy enhancement not enabled, return a constant true checker
return { create: true, read: true, update: true, delete: true };
}
else {
const result = (_a = this.options.policy.checker) === null || _a === void 0 ? void 0 : _a[(0, lower_case_first_1.lowerCaseFirst)(model)];
if (!result) {
// checker generation not enabled, return constant false checker
throw new Error(`Generated permission checkers not found. Please make sure the "generatePermissionChecker" option is set to true in the "@core/enhancer" plugin.`);
}
return result;
}
}
//#endregion
/**
* Gets unique constraints for the given model.

@@ -532,2 +565,5 @@ */

for (const field of (0, cross_1.getModelFields)(injectTarget)) {
if (injectTarget[field] === false) {
continue;
}
const fieldInfo = (0, cross_1.resolveField)(this.modelMeta, model, field);

@@ -780,2 +816,6 @@ if (!fieldInfo || !fieldInfo.isDataModel) {

doInjectReadCheckSelect(model, args, input) {
// omit should be ignored to avoid interfering with field selection
if (args.omit) {
delete args.omit;
}
if (!(input === null || input === void 0 ? void 0 : input.select)) {

@@ -924,3 +964,3 @@ return;

doPostProcessForRead(data, model, fullData, queryArgs, hasFieldLevelPolicy, path = '') {
var _a, _b;
var _a, _b, _c;
if (data === null || data === undefined) {

@@ -942,2 +982,7 @@ return;

}
if (((_a = queryArgs === null || queryArgs === void 0 ? void 0 : queryArgs.omit) === null || _a === void 0 ? void 0 : _a[field]) === true) {
// respect `{ omit: { [field]: true } }`
delete entityData[field];
continue;
}
if (hasFieldLevelPolicy) {

@@ -976,3 +1021,3 @@ // 1. remove fields selected for checking field-level policies but not selected by the original query args

// recurse into nested fields
const nextArgs = (_b = ((_a = queryArgs === null || queryArgs === void 0 ? void 0 : queryArgs.select) !== null && _a !== void 0 ? _a : queryArgs === null || queryArgs === void 0 ? void 0 : queryArgs.include)) === null || _b === void 0 ? void 0 : _b[field];
const nextArgs = (_c = ((_b = queryArgs === null || queryArgs === void 0 ? void 0 : queryArgs.select) !== null && _b !== void 0 ? _b : queryArgs === null || queryArgs === void 0 ? void 0 : queryArgs.include)) === null || _c === void 0 ? void 0 : _c[field];
this.doPostProcessForRead(fieldData, fieldInfo.type, entityFullData[field], nextArgs, this.hasFieldLevelPolicy(fieldInfo.type), path ? path + '.' + field : field);

@@ -979,0 +1024,0 @@ }

import { z } from 'zod';
import { FIELD_LEVEL_OVERRIDE_READ_GUARD_PREFIX, FIELD_LEVEL_OVERRIDE_UPDATE_GUARD_PREFIX, FIELD_LEVEL_READ_CHECKER_PREFIX, FIELD_LEVEL_READ_CHECKER_SELECTOR, FIELD_LEVEL_UPDATE_GUARD_PREFIX, HAS_FIELD_LEVEL_POLICY_FLAG, PRE_UPDATE_VALUE_SELECTOR } from '../constants';
import type { CrudContract, PolicyOperationKind, QueryContext } from '../types';
import type { CheckerContext, CrudContract, PolicyCrudKind, PolicyOperationKind, QueryContext } from '../types';
/**

@@ -24,2 +24,49 @@ * Common options for PrismaClient enhancements

/**
* Function for checking if an operation is possibly allowed.
*/
export type CheckerFunc = (context: CheckerContext) => CheckerConstraint;
/**
* Supported checker constraint checking value types.
*/
export type ConstraintValueTypes = 'boolean' | 'number' | 'string';
/**
* Free variable constraint
*/
export type VariableConstraint = {
kind: 'variable';
name: string;
type: ConstraintValueTypes;
};
/**
* Constant value constraint
*/
export type ValueConstraint = {
kind: 'value';
value: number | boolean | string;
type: ConstraintValueTypes;
};
/**
* Terms for comparison constraints
*/
export type ComparisonTerm = VariableConstraint | ValueConstraint;
/**
* Comparison constraint
*/
export type ComparisonConstraint = {
kind: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte';
left: ComparisonTerm;
right: ComparisonTerm;
};
/**
* Logical constraint
*/
export type LogicalConstraint = {
kind: 'and' | 'or' | 'not';
children: CheckerConstraint[];
};
/**
* Operation allowability checking constraint
*/
export type CheckerConstraint = ValueConstraint | VariableConstraint | ComparisonConstraint | LogicalConstraint;
/**
* Function for getting policy guard with a given context

@@ -41,2 +88,3 @@ */

}>;
checker?: Record<string, Record<PolicyCrudKind, CheckerFunc | boolean>>;
validation: Record<string, {

@@ -43,0 +91,0 @@ hasValidation: boolean;

{
"name": "@zenstackhq/runtime",
"displayName": "ZenStack Runtime Library",
"version": "2.0.3",
"version": "2.1.0",
"description": "Runtime of ZenStack for both client-side and server-side environments.",

@@ -25,2 +25,6 @@ "repository": {

},
"./constraint-solver": {
"types": "./constraint-solver.d.ts",
"default": "./constraint-solver.js"
},
"./zod": {

@@ -76,2 +80,3 @@ "types": "./zod/index.d.ts",

"deepmerge": "^4.3.1",
"logic-solver": "^2.0.1",
"lower-case-first": "^2.0.2",

@@ -83,2 +88,3 @@ "pluralize": "^8.0.0",

"tiny-invariant": "^1.3.1",
"ts-pattern": "^4.3.0",
"tslib": "^2.4.1",

@@ -85,0 +91,0 @@ "upper-case-first": "^2.0.2",

@@ -28,2 +28,3 @@ export type PrismaPromise<T> = Promise<T> & Record<string, (args?: any) => PrismaPromise<any>>;

subscribe(args?: unknown): Promise<any>;
check(args: unknown): Promise<boolean>;
fields: Record<string, any>;

@@ -35,6 +36,7 @@ }

export type PolicyKind = 'allow' | 'deny';
export type PolicyCrudKind = 'read' | 'create' | 'update' | 'delete';
/**
* Kinds of operations controlled by access policies
*/
export type PolicyOperationKind = 'create' | 'update' | 'postUpdate' | 'read' | 'delete';
export type PolicyOperationKind = PolicyCrudKind | 'postUpdate';
/**

@@ -58,2 +60,15 @@ * Current login user info

/**
* Context for checking operation allowability.
*/
export type CheckerContext = {
/**
* Current user
*/
user?: AuthUser;
/**
* Extra field value filters.
*/
fieldValues?: Record<string, string | number | boolean>;
};
/**
* Prisma contract for CRUD operations.

@@ -60,0 +75,0 @@ */

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc