import mergeWith from "lodash/mergeWith" ; import isEmpty from "lodash/isEmpty" ; import { CmsModel } from "./types" ; type Group = { [ code ] : string [ ] ; } ; type Model = { [ code ] : string [ ] ; } ; type CMSPermission = { name : string ; rwd ? : string ; pw ? : string ; own ? : boolean ; groups ? : Group ; models ? : Model ; } ; enum AccessTypes { FULL = "cms.*" , CONTENT_MODEL_GROUP = "cms.contentModelGroup" , CONTENT_MODEL = "cms.contentModel" , CONTENT_ENTRY = "cms.contentEntry" } export const migrateCMSPermissions = async ( permissions , getModel ) : Promise < CMSPermission [ ] > => { const fullAccess = permissions . find ( permission => permission . name === AccessTypes . FULL ) ; if ( fullAccess ) { return permissions ; } const newPermissions = { } ; const DEFAULT_PERMISSIONS = { [ AccessTypes . CONTENT_MODEL_GROUP ] : { name : AccessTypes . CONTENT_MODEL_GROUP , rwd : "r" , own : false } , [ AccessTypes . CONTENT_MODEL ] : { name : AccessTypes . CONTENT_MODEL , rwd : "r" , own : false } , [ AccessTypes . CONTENT_ENTRY ] : { name : AccessTypes . CONTENT_ENTRY , rwd : "r" , own : false } } ; [ AccessTypes . CONTENT_MODEL_GROUP , AccessTypes . CONTENT_MODEL , AccessTypes . CONTENT_ENTRY ] . forEach ( entity => { const existingPermission = permissions . find ( permission => permission . name === entity ) ; if ( existingPermission ) { newPermissions [ entity ] = existingPermission ; } else { newPermissions [ entity ] = DEFAULT_PERMISSIONS [ entity ] ; } if ( entity === AccessTypes . CONTENT_MODEL_GROUP ) { if ( newPermissions [ entity ] . own ) { setAccessScopeToOwn ( newPermissions , entity ) ; } } if ( entity === AccessTypes . CONTENT_MODEL ) { if ( newPermissions [ entity ] . own ) { setAccessScopeToOwn ( newPermissions , entity ) ; } if ( newPermissions [ AccessTypes . CONTENT_MODEL_GROUP ] . own ) { setAccessScopeToOwn ( newPermissions , entity ) ; } if ( newPermissions [ entity ] . groups ) { moveGroups ( newPermissions , entity ) ; } } if ( entity === AccessTypes . CONTENT_ENTRY ) { if ( newPermissions [ entity ] . own ) { setAccessScopeToOwn ( newPermissions , entity ) ; } if ( newPermissions [ AccessTypes . CONTENT_MODEL ] . own ) { setAccessScopeToOwn ( newPermissions , entity ) ; } if ( newPermissions [ entity ] . groups ) { moveGroups ( newPermissions , entity ) ; } if ( newPermissions [ entity ] . models ) { moveModels ( newPermissions , entity ) ; } } } ) ; const contentModels = newPermissions [ AccessTypes . CONTENT_MODEL ] . models ; if ( ! isEmpty ( contentModels ) ) { const contentModelGroups = newPermissions [ AccessTypes . CONTENT_MODEL_GROUP ] . groups || { } ; const locales = Object . keys ( contentModels ) ; for ( let i = 0 ; i < locales . length ; i ++ ) { const code = locales [ i ] ; for ( let j = 0 ; j < contentModels [ code ] . length ; j ++ ) { const modelId = contentModels [ code ] [ j ] ; const { group } = await getModel ( modelId ) ; if ( isEmpty ( contentModelGroups [ code ] ) ) { contentModelGroups [ code ] = [ ] ; } if ( ! contentModelGroups [ code ] . includes ( group . id ) ) { contentModelGroups [ code ] . push ( group . id ) ; } } } newPermissions [ AccessTypes . CONTENT_MODEL_GROUP ] . groups = contentModelGroups ; } return Object . values ( newPermissions ) ; } ; const mergeCustomizer = ( objValue , srcValue ) => { if ( Array . isArray ( objValue ) ) { return objValue . concat ( srcValue ) . filter ( removeDuplicate ) ; } } ; const removeDuplicate = ( item , index , arr ) => arr . findIndex ( el => el === item ) === index ; const moveGroups = ( permissions , entity ) => { if ( ! isEmpty ( permissions [ AccessTypes . CONTENT_MODEL_GROUP ] [ "groups" ] ) ) { permissions [ AccessTypes . CONTENT_MODEL_GROUP ] [ "groups" ] = mergeWith ( permissions [ AccessTypes . CONTENT_MODEL_GROUP ] [ "groups" ] , permissions [ entity ] . groups , mergeCustomizer ) ; } else { permissions [ AccessTypes . CONTENT_MODEL_GROUP ] [ "groups" ] = permissions [ entity ] . groups ; } delete permissions [ entity ] . groups ; } ; const moveModels = ( permissions , entity ) => { if ( ! isEmpty ( permissions [ AccessTypes . CONTENT_MODEL ] [ "models" ] ) ) { permissions [ AccessTypes . CONTENT_MODEL ] [ "models" ] = mergeWith ( permissions [ AccessTypes . CONTENT_MODEL ] [ "models" ] , permissions [ entity ] . models , mergeCustomizer ) ; } else { permissions [ AccessTypes . CONTENT_MODEL ] [ "models" ] = permissions [ entity ] . models ; } delete permissions [ entity ] . models ; } ; const setAccessScopeToOwn = ( permissions , entity ) => { permissions [ entity ] . own = true ; permissions [ entity ] . rwd = "rwd" ; delete permissions [ entity ] . groups ; delete permissions [ entity ] . models ; } ;