{"version":3,"file":"index.mjs","sources":["../../../../src/services/content-api/permissions/index.ts"],"sourcesContent":["import _ from 'lodash';\nimport type { Core } from '@strapi/types';\nimport { createActionProvider, createConditionProvider } from './providers';\nimport createPermissionEngine from './engine';\n\nconst typeSymbol = Symbol.for('__type__');\n\ninterface ValidatePermissionHandler {\n (params: { permission: { action: string } }): boolean;\n}\n\n/**\n * Creates a handler that checks if the permission's action exists in the action registry\n */\nconst createValidatePermissionHandler =\n (actionProvider: ReturnType): ValidatePermissionHandler =>\n ({ permission }) => {\n const action = actionProvider.get(permission.action);\n\n // If the action isn't registered into the action provider, then ignore the permission and warn the user\n if (!action) {\n strapi.log.debug(\n `Unknown action \"${permission.action}\" supplied when registering a new permission`\n );\n\n return false;\n }\n\n return true;\n };\n\n/**\n * Create instances of providers and permission engine for the core content-API service.\n * Also, expose utilities to get information about available actions and such.\n */\nexport default (strapi: Core.Strapi) => {\n // NOTE: Here we define both an action and condition provider,\n // but at the moment, we're only using the action one.\n const providers = {\n action: createActionProvider(),\n condition: createConditionProvider(),\n };\n\n /**\n * Get a tree representation of the available Content API actions\n * based on the methods of the Content API controllers.\n *\n * @note Only actions bound to a content-API route are returned.\n */\n const getActionsMap = () => {\n const actionMap: Record<\n string,\n {\n controllers: Record;\n }\n > = {};\n\n /**\n * Check if a controller's action is bound to the\n * content-api by looking at a potential __type__ symbol\n */\n const isContentApi = (action: Core.ControllerHandler & { [s: symbol]: any }) => {\n if (!_.has(action, typeSymbol)) {\n return false;\n }\n\n return action[typeSymbol].includes('content-api');\n };\n\n /**\n * Register actions from a specific API source into the result tree\n */\n const registerAPIsActions = (\n apis: Record,\n source: 'api' | 'plugin'\n ) => {\n _.forEach(apis, (api, apiName) => {\n const controllers = _.reduce(\n api.controllers,\n (acc, controller, controllerName) => {\n const contentApiActions = _.pickBy(controller, isContentApi);\n\n if (_.isEmpty(contentApiActions)) {\n return acc;\n }\n\n acc[controllerName] = Object.keys(contentApiActions);\n\n return acc;\n },\n {} as Record\n );\n\n if (!_.isEmpty(controllers)) {\n actionMap[`${source}::${apiName}`] = { controllers };\n }\n });\n };\n\n registerAPIsActions(strapi.apis, 'api');\n registerAPIsActions(strapi.plugins, 'plugin');\n\n return actionMap;\n };\n\n /**\n * Register all the content-API controllers actions into the action provider.\n * This method make use of the {@link getActionsMap} to generate the list of actions to register.\n */\n const registerActions = async () => {\n const actionsMap = getActionsMap();\n\n // For each API\n for (const [api, value] of Object.entries(actionsMap)) {\n const { controllers } = value;\n\n // Register controllers methods as actions\n for (const [controller, actions] of Object.entries(controllers)) {\n // Register each action individually\n await Promise.all(\n actions.map((action) => {\n const actionUID = `${api}.${controller}.${action}`;\n\n return providers.action.register(actionUID, {\n api,\n controller,\n action,\n uid: actionUID,\n });\n })\n );\n }\n }\n };\n\n // Create an instance of a content-API permission engine\n // and binds a custom validation handler to it\n const engine = createPermissionEngine({ providers });\n\n engine.on(\n 'before-format::validate.permission',\n createValidatePermissionHandler(providers.action)\n );\n\n return {\n engine,\n providers,\n registerActions,\n getActionsMap,\n };\n};\n"],"names":["typeSymbol","Symbol","for","createValidatePermissionHandler","actionProvider","permission","action","get","strapi","log","debug","providers","createActionProvider","condition","createConditionProvider","getActionsMap","actionMap","isContentApi","_","has","includes","registerAPIsActions","apis","source","forEach","api","apiName","controllers","reduce","acc","controller","controllerName","contentApiActions","pickBy","isEmpty","Object","keys","plugins","registerActions","actionsMap","value","entries","actions","Promise","all","map","actionUID","register","uid","engine","createPermissionEngine","on"],"mappings":";;;;;AAKA,MAAMA,UAAAA,GAAaC,MAAAA,CAAOC,GAAG,CAAC,UAAA,CAAA;AAM9B;;AAEC,IACD,MAAMC,+BAAAA,GACJ,CAACC,iBACD,CAAC,EAAEC,UAAU,EAAE,GAAA;AACb,QAAA,MAAMC,MAAAA,GAASF,cAAAA,CAAeG,GAAG,CAACF,WAAWC,MAAM,CAAA;;AAGnD,QAAA,IAAI,CAACA,MAAAA,EAAQ;YACXE,MAAAA,CAAOC,GAAG,CAACC,KAAK,CACd,CAAC,gBAAgB,EAAEL,UAAAA,CAAWC,MAAM,CAAC,4CAA4C,CAAC,CAAA;YAGpF,OAAO,KAAA;AACT,QAAA;QAEA,OAAO,IAAA;AACT,IAAA,CAAA;AAEF;;;IAIA,sCAAe,CAAA,CAACE,OAAAA,GAAAA;;;AAGd,IAAA,MAAMG,SAAAA,GAAY;QAChBL,MAAAA,EAAQM,oBAAAA,EAAAA;QACRC,SAAAA,EAAWC,uBAAAA;AACb,KAAA;AAEA;;;;;AAKC,MACD,MAAMC,aAAAA,GAAgB,IAAA;AACpB,QAAA,MAAMC,YAKF,EAAC;AAEL;;;QAIA,MAAMC,eAAe,CAACX,MAAAA,GAAAA;AACpB,YAAA,IAAI,CAACY,CAAAA,CAAEC,GAAG,CAACb,QAAQN,UAAAA,CAAAA,EAAa;gBAC9B,OAAO,KAAA;AACT,YAAA;AAEA,YAAA,OAAOM,MAAM,CAACN,UAAAA,CAAW,CAACoB,QAAQ,CAAC,aAAA,CAAA;AACrC,QAAA,CAAA;AAEA;;QAGA,MAAMC,mBAAAA,GAAsB,CAC1BC,IAAAA,EACAC,MAAAA,GAAAA;AAEAL,YAAAA,CAAAA,CAAEM,OAAO,CAACF,IAAAA,EAAM,CAACG,GAAAA,EAAKC,OAAAA,GAAAA;gBACpB,MAAMC,WAAAA,GAAcT,EAAEU,MAAM,CAC1BH,IAAIE,WAAW,EACf,CAACE,GAAAA,EAAKC,UAAAA,EAAYC,cAAAA,GAAAA;AAChB,oBAAA,MAAMC,iBAAAA,GAAoBd,CAAAA,CAAEe,MAAM,CAACH,UAAAA,EAAYb,YAAAA,CAAAA;oBAE/C,IAAIC,CAAAA,CAAEgB,OAAO,CAACF,iBAAAA,CAAAA,EAAoB;wBAChC,OAAOH,GAAAA;AACT,oBAAA;AAEAA,oBAAAA,GAAG,CAACE,cAAAA,CAAe,GAAGI,MAAAA,CAAOC,IAAI,CAACJ,iBAAAA,CAAAA;oBAElC,OAAOH,GAAAA;AACT,gBAAA,CAAA,EACA,EAAC,CAAA;AAGH,gBAAA,IAAI,CAACX,CAAAA,CAAEgB,OAAO,CAACP,WAAAA,CAAAA,EAAc;AAC3BX,oBAAAA,SAAS,CAAC,CAAA,EAAGO,MAAAA,CAAO,EAAE,EAAEG,OAAAA,CAAAA,CAAS,CAAC,GAAG;AAAEC,wBAAAA;AAAY,qBAAA;AACrD,gBAAA;AACF,YAAA,CAAA,CAAA;AACF,QAAA,CAAA;QAEAN,mBAAAA,CAAoBb,OAAAA,CAAOc,IAAI,EAAE,KAAA,CAAA;QACjCD,mBAAAA,CAAoBb,OAAAA,CAAO6B,OAAO,EAAE,QAAA,CAAA;QAEpC,OAAOrB,SAAAA;AACT,IAAA,CAAA;AAEA;;;AAGC,MACD,MAAMsB,eAAAA,GAAkB,UAAA;AACtB,QAAA,MAAMC,UAAAA,GAAaxB,aAAAA,EAAAA;;QAGnB,KAAK,MAAM,CAACU,GAAAA,EAAKe,KAAAA,CAAM,IAAIL,MAAAA,CAAOM,OAAO,CAACF,UAAAA,CAAAA,CAAa;YACrD,MAAM,EAAEZ,WAAW,EAAE,GAAGa,KAAAA;;YAGxB,KAAK,MAAM,CAACV,UAAAA,EAAYY,OAAAA,CAAQ,IAAIP,MAAAA,CAAOM,OAAO,CAACd,WAAAA,CAAAA,CAAc;;AAE/D,gBAAA,MAAMgB,QAAQC,GAAG,CACfF,OAAAA,CAAQG,GAAG,CAAC,CAACvC,MAAAA,GAAAA;oBACX,MAAMwC,SAAAA,GAAY,GAAGrB,GAAAA,CAAI,CAAC,EAAEK,UAAAA,CAAW,CAAC,EAAExB,MAAAA,CAAAA,CAAQ;AAElD,oBAAA,OAAOK,SAAAA,CAAUL,MAAM,CAACyC,QAAQ,CAACD,SAAAA,EAAW;AAC1CrB,wBAAAA,GAAAA;AACAK,wBAAAA,UAAAA;AACAxB,wBAAAA,MAAAA;wBACA0C,GAAAA,EAAKF;AACP,qBAAA,CAAA;AACF,gBAAA,CAAA,CAAA,CAAA;AAEJ,YAAA;AACF,QAAA;AACF,IAAA,CAAA;;;AAIA,IAAA,MAAMG,SAASC,sBAAAA,CAAuB;AAAEvC,QAAAA;AAAU,KAAA,CAAA;AAElDsC,IAAAA,MAAAA,CAAOE,EAAE,CACP,oCAAA,EACAhD,+BAAAA,CAAgCQ,UAAUL,MAAM,CAAA,CAAA;IAGlD,OAAO;AACL2C,QAAAA,MAAAA;AACAtC,QAAAA,SAAAA;AACA2B,QAAAA,eAAAA;AACAvB,QAAAA;AACF,KAAA;AACF,CAAA;;;;"}