UNPKG

@speckle/shared

Version:

Shared code between various Speckle JS packages

117 lines 4.79 kB
import { err, ok } from 'true-myth/result'; import { ProjectNotEnoughPermissionsError, SavedViewGroupNotFoundError, SavedViewNoAccessError, SavedViewNotFoundError, UngroupedSavedViewGroupLockError } from '../domain/authErrors.js'; import { SavedViewVisibility } from '../domain/savedViews/types.js'; import { ensureCanUseProjectWorkspacePlanFeatureFragment, ensureImplicitProjectMemberWithWriteAccessFragment } from './projects.js'; import { Roles } from '../../core/constants.js'; import { WorkspacePlanFeatures } from '../../workspaces/index.js'; import { isUngroupedGroup } from '../../saved-views/index.js'; import { StringEnum, throwUncoveredError } from '../../core/index.js'; export const WriteTypes = StringEnum([ 'UpdateGeneral', 'MoveView', 'EditTitle', 'EditDescription', 'SetHomeView' ]); /** * Ensure the user can access the view */ export const ensureCanAccessSavedViewFragment = (loaders) => async ({ userId, projectId, savedViewId, access, allowNonExistent }) => { const canUseSavedViews = await ensureCanUseProjectWorkspacePlanFeatureFragment(loaders)({ projectId, feature: WorkspacePlanFeatures.SavedViews }); if (canUseSavedViews.isErr) return err(canUseSavedViews.error); const savedView = await loaders.getSavedView({ projectId, savedViewId }); if (!savedView) { if (allowNonExistent) return ok(); return err(new SavedViewNotFoundError()); } const isPublic = savedView.visibility === SavedViewVisibility.public; const isAuthor = savedView.authorId === userId; // Validate read access if (access === 'read') { if (isAuthor || isPublic) { return ok(); } else { return err(new SavedViewNoAccessError({ message: 'You do not have permission to read this saved view.' })); } } // Validate write access // Check for write access to project first const ensuredWriteAccess = await ensureImplicitProjectMemberWithWriteAccessFragment(loaders)({ userId, projectId }); if (ensuredWriteAccess.isErr) { if (ensuredWriteAccess.error.code === ProjectNotEnoughPermissionsError.code) return err(new ProjectNotEnoughPermissionsError({ message: "Your role on this project doesn't give you permission to update views." })); return err(ensuredWriteAccess.error); } if (isAuthor) { // authors can write whatever return ok(); } // Non-author project writers can make specific changes switch (access) { case WriteTypes.MoveView: case WriteTypes.EditTitle: case WriteTypes.EditDescription: case WriteTypes.SetHomeView: return ok(); case WriteTypes.UpdateGeneral: return err(new SavedViewNoAccessError({ message: 'You do not have permission to edit the view in this way' })); default: throwUncoveredError(access); } }; /** * Ensure the user can access the view group */ export const ensureCanAccessSavedViewGroupFragment = (loaders) => async ({ userId, projectId, savedViewGroupId, access }) => { const canUseSavedViews = await ensureCanUseProjectWorkspacePlanFeatureFragment(loaders)({ projectId, feature: WorkspacePlanFeatures.SavedViews }); if (canUseSavedViews.isErr) return err(canUseSavedViews.error); const savedViewGroup = await loaders.getSavedViewGroup({ projectId, groupId: savedViewGroupId }); if (!savedViewGroup) return err(new SavedViewGroupNotFoundError()); if (access === 'read') { return ok(); // read access available to everyone who has access to project } // Prevent default group updates (as it doesnt exist) if (isUngroupedGroup(savedViewGroup.id)) { return err(new UngroupedSavedViewGroupLockError()); } // groups have no visibility (yet), so authors AND project owners can mutate const isAuthor = savedViewGroup.authorId === userId; const expectedProjectRole = isAuthor ? Roles.Stream.Contributor : Roles.Stream.Owner; const ensuredWriteAccess = await ensureImplicitProjectMemberWithWriteAccessFragment(loaders)({ userId, projectId, role: expectedProjectRole }); if (ensuredWriteAccess.isErr) { if (ensuredWriteAccess.error.code === ProjectNotEnoughPermissionsError.code) return err(new ProjectNotEnoughPermissionsError({ message: "Your role on this project doesn't give you permission to update view groups." })); return err(ensuredWriteAccess.error); } return ok(); }; //# sourceMappingURL=savedViews.js.map