UNPKG

@speckle/shared

Version:

Shared code between various Speckle JS packages

203 lines 9.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ensureCanUseProjectWorkspacePlanFeatureFragment = exports.ensureImplicitProjectMemberWithWriteAccessFragment = exports.ensureImplicitProjectMemberWithReadAccessFragment = exports.checkIfPubliclyReadableProjectFragment = exports.ensureProjectWorkspaceAccessFragment = exports.ensureMinimumProjectRoleFragment = void 0; const result_1 = require("true-myth/result"); const authErrors_js_1 = require("../domain/authErrors.js"); const constants_js_1 = require("../../core/constants.js"); const roles_js_1 = require("../domain/logic/roles.js"); const projects_js_1 = require("../checks/projects.js"); const workspaces_js_1 = require("./workspaces.js"); const server_js_1 = require("./server.js"); const types_js_1 = require("../domain/projects/types.js"); const workspaceRoleImplicitProjectRoleMap = (projectVisibility) => { const isFullyPrivate = projectVisibility === types_js_1.ProjectVisibility.Private; return { [constants_js_1.Roles.Workspace.Admin]: constants_js_1.Roles.Stream.Owner, [constants_js_1.Roles.Workspace.Member]: isFullyPrivate ? null : constants_js_1.Roles.Stream.Reviewer, [constants_js_1.Roles.Workspace.Guest]: null }; }; /** * Ensure user has a minimum explicit or implicit project role */ const ensureMinimumProjectRoleFragment = (loaders) => async ({ userId, projectId, role, explicit }) => { const requiredProjectRole = role || constants_js_1.Roles.Stream.Reviewer; const isTestingForMinimumAccess = requiredProjectRole === constants_js_1.Roles.Stream.Reviewer; const env = await loaders.getEnv(); const project = await loaders.getProject({ projectId }); if (!project) return (0, result_1.err)(new authErrors_js_1.ProjectNotFoundError()); // Check for explicit project role first const hasExplicitProjectRole = await (0, projects_js_1.hasMinimumProjectRole)(loaders)({ userId, projectId, role: requiredProjectRole }); if (hasExplicitProjectRole) return (0, result_1.ok)(); // Now check if there's an implicit one const { workspaceId } = project; if (env.FF_WORKSPACES_MODULE_ENABLED && !!workspaceId) { // Check for implicit workspace project role const userWorkspaceRole = await loaders.getWorkspaceRole({ userId, workspaceId }); if (userWorkspaceRole) { const implicitProjectRole = explicit ? null : workspaceRoleImplicitProjectRoleMap(project.visibility)[userWorkspaceRole]; if (implicitProjectRole) { // Does it fit minimum? if ((0, roles_js_1.isMinimumProjectRole)(implicitProjectRole, requiredProjectRole)) { return (0, result_1.ok)(); } else { // Have some permissions, but not enough return (0, result_1.err)(new authErrors_js_1.ProjectNotEnoughPermissionsError()); } } } } // Do we have any role at all? const anyRoleFound = await loaders.getProjectRole({ userId, projectId }); return (0, result_1.err)(isTestingForMinimumAccess || !anyRoleFound ? new authErrors_js_1.ProjectNoAccessError() : new authErrors_js_1.ProjectNotEnoughPermissionsError()); }; exports.ensureMinimumProjectRoleFragment = ensureMinimumProjectRoleFragment; /** * Ensure user has access to the project's workspace (has role & SSO session, if any), if it has one */ const ensureProjectWorkspaceAccessFragment = (loaders) => async ({ userId, projectId }) => { const env = await loaders.getEnv(); const project = await loaders.getProject({ projectId }); if (!project) return (0, result_1.err)(new authErrors_js_1.ProjectNotFoundError()); const { workspaceId } = project; if (!workspaceId || !env.FF_WORKSPACES_MODULE_ENABLED) return (0, result_1.ok)(); const memberWithSsoSession = await (0, workspaces_js_1.ensureWorkspaceRoleAndSessionFragment)(loaders)({ userId, workspaceId }); if (memberWithSsoSession.isErr) { switch (memberWithSsoSession.error.code) { case authErrors_js_1.WorkspaceNoAccessError.code: return (0, result_1.err)(new authErrors_js_1.WorkspaceNoAccessError("You do not have access to this project's workspace")); default: return (0, result_1.err)(memberWithSsoSession.error); } } return memberWithSsoSession; }; exports.ensureProjectWorkspaceAccessFragment = ensureProjectWorkspaceAccessFragment; /** * Check if project is publicly readable or not */ const checkIfPubliclyReadableProjectFragment = (loaders) => async ({ projectId }) => { const project = await loaders.getProject({ projectId }); if (!project) return (0, result_1.err)(new authErrors_js_1.ProjectNotFoundError()); return (0, result_1.ok)(await (0, projects_js_1.isPubliclyReadableProject)(loaders)({ projectId })); }; exports.checkIfPubliclyReadableProjectFragment = checkIfPubliclyReadableProjectFragment; /** * Ensure user has implicit/explicit project membership and read access */ const ensureImplicitProjectMemberWithReadAccessFragment = (loaders) => async ({ userId, projectId, role }) => { // Ensure user is authed const ensuredServerRole = await (0, server_js_1.ensureMinimumServerRoleFragment)(loaders)({ userId, role: constants_js_1.Roles.Server.Guest }); if (ensuredServerRole.isErr) { return (0, result_1.err)(ensuredServerRole.error); } // Check if user has admin override enabled const isAdminOverrideEnabled = await (0, server_js_1.checkIfAdminOverrideEnabledFragment)(loaders)({ userId }); if (isAdminOverrideEnabled.isErr) { return (0, result_1.err)(isAdminOverrideEnabled.error); } if (isAdminOverrideEnabled.value) return (0, result_1.ok)(); // And ensure (implicit/explicit) project role const ensuredProjectRole = await (0, exports.ensureMinimumProjectRoleFragment)(loaders)({ userId: userId, projectId, role }); if (ensuredProjectRole.isErr) { return (0, result_1.err)(ensuredProjectRole.error); } // No god mode, ensure workspace access const ensuredWorkspaceAccess = await (0, exports.ensureProjectWorkspaceAccessFragment)(loaders)({ userId: userId, projectId }); if (ensuredWorkspaceAccess.isErr) { return (0, result_1.err)(ensuredWorkspaceAccess.error); } return (0, result_1.ok)(); }; exports.ensureImplicitProjectMemberWithReadAccessFragment = ensureImplicitProjectMemberWithReadAccessFragment; /** * Ensure user has implicit/explicit project membership and write access */ const ensureImplicitProjectMemberWithWriteAccessFragment = (loaders) => async ({ userId, projectId, role }) => { const requiredProjectRole = role || constants_js_1.Roles.Stream.Contributor; const requiredServerRole = requiredProjectRole === constants_js_1.Roles.Stream.Owner ? constants_js_1.Roles.Server.User : constants_js_1.Roles.Server.Guest; // Ensure user is authed const ensuredServerRole = await (0, server_js_1.ensureMinimumServerRoleFragment)(loaders)({ userId, role: requiredServerRole }); if (ensuredServerRole.isErr) { return (0, result_1.err)(ensuredServerRole.error); } // And ensure (implicit/explicit) project role const ensuredProjectRole = await (0, exports.ensureMinimumProjectRoleFragment)(loaders)({ userId: userId, projectId, role: requiredProjectRole }); if (ensuredProjectRole.isErr) { return (0, result_1.err)(ensuredProjectRole.error); } // Ensure workspace access const ensuredWorkspaceAccess = await (0, exports.ensureProjectWorkspaceAccessFragment)(loaders)({ userId: userId, projectId }); if (ensuredWorkspaceAccess.isErr) { return (0, result_1.err)(ensuredWorkspaceAccess.error); } return (0, result_1.ok)(); }; exports.ensureImplicitProjectMemberWithWriteAccessFragment = ensureImplicitProjectMemberWithWriteAccessFragment; /** * Ensure project is workspaced and has access to a specific plan feature */ const ensureCanUseProjectWorkspacePlanFeatureFragment = (loaders) => async ({ projectId, feature, allowUnworkspaced = false }) => { const project = await loaders.getProject({ projectId }); if (!project) return (0, result_1.err)(new authErrors_js_1.ProjectNotFoundError()); const workspaceId = project.workspaceId; if (!workspaceId) { if (allowUnworkspaced) return (0, result_1.ok)(); return (0, result_1.err)(new authErrors_js_1.WorkspaceNoAccessError({ message: 'The project must be in a workspace' })); } const canUseFeature = await (0, workspaces_js_1.ensureCanUseWorkspacePlanFeatureFragment)(loaders)({ workspaceId, feature }); if (canUseFeature.isErr) return (0, result_1.err)(canUseFeature.error); return (0, result_1.ok)(); }; exports.ensureCanUseProjectWorkspacePlanFeatureFragment = ensureCanUseProjectWorkspacePlanFeatureFragment; //# sourceMappingURL=projects.js.map