/** * External dependencies */ import { flatten, keys, values } from 'lodash'; import { isEmpty } from '@nelio-content/utils'; import type { EditorialTask, Post, PostCapability, PostTypeName, PremiumItem, PremiumItemType, RoleId, SocialMessage, UserId, } from '@nelio-content/types'; /** * Internal dependencies */ import { isSubscribed } from '../plugin/selectors'; import { canCurrentUserUseProfileId, getProfilesWithoutMessagesRelatedToPost, } from '../../social/selectors'; import type { State } from '../../config'; export function getCurrentUserId( state: State ): UserId { return state.meta.user.id; } export function getCurrentUserRole( state: State ): RoleId { return state.meta.user.role; } export function canCurrentUser( state: State, capability: PostCapability, postType?: PostTypeName ): boolean { if ( ! postType ) { return false; } const data = state.meta.user.postTypeCapabilities; const permissions = data[ postType ]; return !! permissions?.includes( capability ); } export function canCurrentUserManagePlugin( state: State ): boolean { return 'manage' === state.meta.user.pluginPermission; } export function canCurrentUserCreatePosts( state: State ): boolean { const data = state.meta.user.postTypeCapabilities || {}; const permissions = flatten( values( data ) ); return permissions.includes( 'create' ); } export function canCurrentUserViewPost( state: State, post?: Post ): boolean { if ( ! post ) { return false; } if ( ! canCurrentUser( state, 'read', post.type ) ) { return false; } if ( state.meta.site.canViewAllCalendarPosts && state.meta.site.postTypesByContext.calendar.includes( post.type ) ) { return true; } if ( 'publish' === post.status ) { return true; } if ( canCurrentUser( state, 'edit-others', post.type ) ) { return true; } const isAuthor = getCurrentUserId( state ) === post.author; return isAuthor && canCurrentUser( state, 'edit-own', post.type ); } export function canCurrentUserEditPost( state: State, post?: Post ): boolean { if ( ! post ) { return false; } if ( canCurrentUser( state, 'edit-others', post.type ) ) { return true; } const isAuthor = getCurrentUserId( state ) === post.author; return isAuthor && canCurrentUser( state, 'edit-own', post.type ); } export function canCurrentUserDeletePost( state: State, post?: Post ): boolean { if ( ! post ) { return false; } if ( canCurrentUser( state, 'delete-others', post.type ) ) { return true; } const isAuthor = getCurrentUserId( state ) === post.author; return isAuthor && canCurrentUser( state, 'delete-own', post.type ); } export function canCurrentUserPublishPost( state: State, post?: Post ): boolean { return !! post && canCurrentUser( state, 'publish', post.type ); } export function canCurrentUserUseAutomationsInPost( state: State, post?: Post ): boolean { if ( ! post ) { return false; } if ( 'none' === state.meta.user.socialEditorPermission ) { return false; } if ( 'all' === state.meta.user.socialEditorPermission ) { return true; } if ( canCurrentUser( state, 'edit-others', post.type ) ) { return true; } const isPostAuthor = getCurrentUserId( state ) === post.author; return isPostAuthor && canCurrentUser( state, 'edit-own', post.type ); } export function canCurrentUserCreateMessagesAlways( state: State ): boolean { return 'all' === state.meta.user.socialEditorPermission; } export function canCurrentUserCreateMessagesRelatedToPost( state: State, post?: Post ): boolean { if ( ! post ) { return false; } if ( isSubscribed( state ) ) { return couldSubscriberCreateMessagesRelatedToPost( state, post ); } const profiles = getProfilesWithoutMessagesRelatedToPost( state, post.id ); return ! isEmpty( profiles ); } export function couldSubscriberCreateMessagesRelatedToPost( state: State, post?: Post ): boolean { return !! post && canCurrentUserUseAutomationsInPost( state, post ); } export function canCurrentUserEditSocialMessage( state: State, message?: SocialMessage ): boolean { if ( ! message ) { return false; } if ( 'none' === state.meta.user.socialEditorPermission ) { return false; } if ( 'publish' === message.status ) { return false; } if ( message.isFreePreview ) { return false; } if ( isEmpty( state.social.profiles.byId[ message.profileId ] ) ) { return false; } if ( ! canCurrentUserUseProfileId( state, message.profileId ) ) { return false; } if ( 'all' === state.meta.user.socialEditorPermission ) { return true; } // NOTE. This block is a workaround to overcome messages that are missing a postType attribute. if ( message.postId && ! message.postType ) { const author = getCurrentUserId( state ) === message.postAuthor; const postTypes = keys( state.meta.site.postTypes ); for ( const pt of postTypes ) { if ( canCurrentUser( state, 'edit-others', pt ) ) { return true; } if ( author && canCurrentUser( state, 'edit-own', pt ) ) { return true; } } return false; } if ( canCurrentUser( state, 'edit-others', message.postType ) ) { return true; } const isRelatedPostAuthor = getCurrentUserId( state ) === message.postAuthor; return ( isRelatedPostAuthor && canCurrentUser( state, 'edit-own', message.postType ) ); } export function canCurrentUserDeleteSocialMessage( state: State, message?: SocialMessage ): boolean { return canCurrentUserEditSocialMessage( state, message ); } export function canCurrentUserCreateTasksAlways( state: State ): boolean { return 'all' === state.meta.user.taskEditorPermission; } export function canCurrentUserCreateTasksRelatedToPost( state: State, post?: Post ): boolean { if ( ! post ) { return false; } if ( 'all' === state.meta.user.taskEditorPermission ) { return true; } if ( 'none' === state.meta.user.taskEditorPermission ) { return false; } if ( canCurrentUser( state, 'edit-others', post.type ) ) { return true; } const isRelatedPostAuthor = getCurrentUserId( state ) === post.author; return ( isRelatedPostAuthor && canCurrentUser( state, 'edit-own', post.type ) ); } export function canCurrentUserEditTask( state: State, task?: EditorialTask ): boolean { if ( ! task ) { return false; } if ( 'none' === state.meta.user.taskEditorPermission ) { return false; } if ( task.assigneeId === getCurrentUserId( state ) ) { return true; } if ( 'all' === state.meta.user.taskEditorPermission ) { return true; } if ( canCurrentUser( state, 'edit-others', task.postType ) ) { return true; } const isRelatedPostAuthor = getCurrentUserId( state ) === task.postAuthor; return ( isRelatedPostAuthor && canCurrentUser( state, 'edit-own', task.postType ) ); } export function canCurrentUserDeleteTask( state: State, task?: EditorialTask ): boolean { if ( ! task ) { return false; } if ( 'none' === state.meta.user.taskEditorPermission ) { return false; } return canCurrentUserEditTask( state, task ); } export function canCurrentUserEditPremiumItem( state: State, typeName: PremiumItemType, item?: PremiumItem ): boolean { if ( ! item ) { return false; } const permission = state.meta.user.premiumEditorPermissionsByType[ typeName ]; if ( ! permission ) { return false; } if ( 'none' === permission ) { return false; } if ( 'all' === permission ) { return true; } if ( canCurrentUser( state, 'edit-others', item.postType ) ) { return true; } const isRelatedPostAuthor = getCurrentUserId( state ) === item.postAuthor; return ( isRelatedPostAuthor && canCurrentUser( state, 'edit-own', item.postType ) ); } export function canCurrentUserViewPremiumItem( state: State, typeName: PremiumItemType, item?: PremiumItem ): boolean { if ( ! item ) { return false; } const permission = state.meta.user.premiumEditorPermissionsByType[ typeName ]; if ( ! permission ) { return false; } if ( canCurrentUserEditPremiumItem( state, typeName, item ) ) { return true; } if ( canCurrentUser( state, 'read', item.postType ) ) { return true; } return false; } export function canCurrentUserDeletePremiumItem( state: State, typeName: PremiumItemType, item?: PremiumItem ): boolean { return canCurrentUserEditPremiumItem( state, typeName, item ); }