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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | 1x 1x 1x 1x 1x 1x 680x 680x 1x 14x 14x 469x 1x 4x 1x 680x 680x 1x 464x 149x 149x 315x 300x 15x 15x 8x 8x 7x 1x 230x 230x 2x 2x 230x 1x 164x 28x 28x 1x 8x 8x 8x 8x 8x 8x 1x 25x 1x 205x 205x 1x 1x 56x 1x 410x | import _get from "lodash/get"; import _set from "lodash/set"; import _unset from "lodash/unset"; import { Forbidden } from "@feathersjs/errors"; import { AnyAbility } from "@casl/ability"; import { Application, HookContext } from "@feathersjs/feathers"; import { isMulti } from "feathers-utils"; import { AuthorizeHookOptions, InitOptions, Path } from "../../types"; export const makeOptions = ( app: Application, options?: Partial<AuthorizeHookOptions> ): AuthorizeHookOptions => { options = options || {}; return Object.assign({}, defaultOptions, getAppOptions(app), options); }; const defaultOptions: AuthorizeHookOptions = { ability: undefined, actionOnForbidden: undefined, availableFields: (context: HookContext): string[] => { const availableFields: string[] | ((context: HookContext) => string[]) = context.service.options?.casl?.availableFields; Eif (!availableFields) return undefined; return (typeof availableFields === "function") ? availableFields(context) : availableFields; }, checkMultiActions: false, checkAbilityForInternal: false, modelName: (context: Pick<HookContext, "path">): string => { return context.path; } }; export const makeDefaultOptions = ( options?: Partial<AuthorizeHookOptions> ): AuthorizeHookOptions => { return Object.assign({}, defaultOptions, options); }; const getAppOptions = (app: Application): AuthorizeHookOptions | Record<string, never> => { const caslOptions: InitOptions = app?.get("casl"); return (caslOptions && caslOptions.authorizeHook) ? caslOptions.authorizeHook : {}; }; export const getAbility = ( context: HookContext, options?: Pick<AuthorizeHookOptions, "ability" | "checkAbilityForInternal"> ): Promise<AnyAbility|undefined> => { // if params.ability is set, return it over options.ability if (context?.params?.ability) { Iif (typeof context.params.ability === "function") { const ability = context.params.ability(context); return Promise.resolve(ability); } else { return Promise.resolve(context.params.ability); } } if (!options.checkAbilityForInternal && !context.params?.provider) { return Promise.resolve(undefined); } Eif (options?.ability) { if (typeof options.ability === "function") { const ability = options.ability(context); return Promise.resolve(ability); } else { return Promise.resolve(options.ability); } } return Promise.resolve(undefined); }; const move = (context: HookContext, fromPath: Path, toPath: Path) => { const val = _get(context, fromPath); if (val !== undefined) { _unset(context, fromPath); _set(context, toPath, val); } return val; }; export const throwUnlessCan = ( ability: AnyAbility, method: string, resource: string|Record<string, unknown>, modelName: string, actionOnForbidden: () => void ): void => { if (ability.cannot(method, resource)) { Iif (actionOnForbidden) actionOnForbidden(); throw new Forbidden(`You are not allowed to ${method} ${modelName}`); } }; export const checkMulti = ( context: HookContext, ability: AnyAbility, modelName: string, options?: Pick<AuthorizeHookOptions, "actionOnForbidden"> ): boolean => { const { method } = context; const currentIsMulti = isMulti(context); Iif (!currentIsMulti) { return true; } Iif ( (method === "find" && ability.can(method, modelName)) || (ability.can(`${method}-multi`, modelName)) ) { return true; } if (options?.actionOnForbidden) options.actionOnForbidden(); throw new Forbidden(`You're not allowed to multi-${method} ${modelName}`); }; export const hide$select = (context: HookContext): unknown => { return move(context, "params.query.$select", "params.casl.$select"); }; export const restore$select = (context: HookContext): string[]|undefined => { move(context, "params.casl.$select", "params.query.$select"); return _get(context, "params.query.$select"); }; export const get$select = (context: HookContext): unknown => { return getPersistedConfig(context, "$select"); }; export const setPersistedConfig = (context: HookContext, key: Path, val: unknown): HookContext => { return _set(context, `params.casl.${key}`, val); }; export const getPersistedConfig = (context: HookContext, key: Path): unknown => { return _get(context, `params.casl.${key}`); }; |