mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 04:27:21 +00:00
- Bump `jsonv-ts` dependency to 0.8.6. - Refactor permission checks in the `Guard` class to improve context validation and error handling. - Update tests to reflect changes in permission handling, ensuring robust coverage for new scenarios. - Introduce new test cases for data permissions, enhancing overall test coverage and reliability.
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { s, parse, recursivelyReplacePlaceholders } from "bknd/utils";
|
|
import * as query from "core/object/query/object-query";
|
|
|
|
export const policySchema = s
|
|
.strictObject({
|
|
description: s.string(),
|
|
condition: s.object({}).optional() as s.Schema<{}, query.ObjectQuery | undefined>,
|
|
// @todo: potentially remove this, and invert from rolePermission.effect
|
|
effect: s.string({ enum: ["allow", "deny", "filter"], default: "allow" }),
|
|
filter: s.object({}).optional() as s.Schema<{}, query.ObjectQuery | undefined>,
|
|
})
|
|
.partial();
|
|
export type PolicySchema = s.Static<typeof policySchema>;
|
|
|
|
export class Policy<Schema extends PolicySchema = PolicySchema> {
|
|
public content: Schema;
|
|
|
|
constructor(content?: Schema) {
|
|
this.content = parse(policySchema, content ?? {}, {
|
|
withDefaults: true,
|
|
}) as Schema;
|
|
}
|
|
|
|
replace(context: object, vars?: Record<string, any>, fallback?: any) {
|
|
return vars
|
|
? recursivelyReplacePlaceholders(context, /^@([a-zA-Z_\.]+)$/, vars, fallback)
|
|
: context;
|
|
}
|
|
|
|
getReplacedFilter(context: object, fallback?: any) {
|
|
if (!this.content.filter) return context;
|
|
return this.replace(this.content.filter!, context, fallback);
|
|
}
|
|
|
|
meetsCondition(context: object, vars?: Record<string, any>) {
|
|
if (!this.content.condition) return true;
|
|
return query.validate(this.replace(this.content.condition!, vars), context);
|
|
}
|
|
|
|
meetsFilter(subject: object, vars?: Record<string, any>) {
|
|
if (!this.content.filter) return true;
|
|
return query.validate(this.replace(this.content.filter!, vars), subject);
|
|
}
|
|
|
|
getFiltered<Given extends any[]>(given: Given): Given {
|
|
return given.filter((item) => this.meetsFilter(item)) as Given;
|
|
}
|
|
|
|
toJSON() {
|
|
return this.content;
|
|
}
|
|
}
|