Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | import _isPlainObject from "lodash/isPlainObject"; import { Forbidden } from "@feathersjs/errors"; import { mergeQuery } from "@artesa/feathers-utils"; import { Ability, RawRuleFrom, AbilityTuple, Subject } from "@casl/ability"; import { Query } from "@feathersjs/feathers"; import { GetConditionalQueryOptions } from "../types"; const invertedMap = { "$gt": "$lte", "$gte": "$lt", "$lt": "$gte", "$lte": "$gt", "$in": "$nin", "$nin": "$in", "$ne": (prop: Record<string, unknown>): unknown => { return prop["$ne"]; } }; const invertedProp = (prop: Record<string, unknown>, name: string): Record<string, unknown>|string => { const map = invertedMap[name]; if (typeof map === "string") { return { [map]: prop[name] }; } else if(typeof map === "function") { return map(prop); } }; const convertRuleToQuery = (rule: RawRuleFrom<AbilityTuple<string, Subject>, unknown>, options: GetConditionalQueryOptions): Query => { const { conditions, inverted } = rule; if (!conditions) { if (inverted && options?.actionOnForbidden) { options.actionOnForbidden(); } return {} as Query; } if (inverted) { const newConditions = {} as Query; for (const prop in (conditions as Record<string, unknown>)) { if (_isPlainObject(conditions[prop])) { const obj = conditions[prop]; for (const name in obj) { if (![ "$gt", "$gte", "$lt", "$lte", "$in", "$nin", "$ne" ].includes(name)) { console.error(`CASL: not supported property: ${name}`); continue; } newConditions[prop] = invertedProp(obj, name); } } else { newConditions[prop] = { $ne: conditions[prop] }; } } return newConditions; } else { return conditions as Query; } }; export default (ability: Ability, method: string, subject: Subject, options?: GetConditionalQueryOptions): Query => { options = options || {}; options.actionOnForbidden = options.actionOnForbidden || (() => { throw new Forbidden("You're not allowed to make this request"); }); const rules = ability.rulesFor(method, subject); let query = {}; for (let i = 0; i < rules.length; i++) { const rule = rules[i]; const currentQuery = convertRuleToQuery(rule, options); query = mergeQuery(query, currentQuery, { defaultHandle: "combine" }); } return query; }; |