@speckle/shared
Version:
Shared code between various Speckle JS packages
117 lines • 4.79 kB
JavaScript
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