[permissions] Enable permissions V1 for all workspaces (#11172)
Closes https://github.com/twentyhq/core-team-issues/issues/526 (for reminder: 1. Make defaultRoleId non-nullable for an active workspace 2. Remove permissions V1 feature flag 3. Set member role as default role for new workspaces About 1.: An active workspace's defaultRoleId should never be null. We can't rely on a simple postgres NOT NULL constraint as defaultRoleId will always be initially null when the workspace is first created since the roles do not exist at that time. Let's add a more complex rule to ensure that About 3.: In the first phase of our deploy of permissions, we chose to assign admin role to all existing users, not to break any existing behavior with the introduction of the feature (= existing users have less rights than before). As we deploy permissions to all existing and future workspaces, let's set the member role as default role for future workspaces. )
This commit is contained in:
@ -4,7 +4,6 @@ import { Route, Routes } from 'react-router-dom';
|
|||||||
import { SettingsProtectedRouteWrapper } from '@/settings/components/SettingsProtectedRouteWrapper';
|
import { SettingsProtectedRouteWrapper } from '@/settings/components/SettingsProtectedRouteWrapper';
|
||||||
import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader';
|
import { SettingsSkeletonLoader } from '@/settings/components/SettingsSkeletonLoader';
|
||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
|
||||||
import { SettingPermissionType } from '~/generated/graphql';
|
import { SettingPermissionType } from '~/generated/graphql';
|
||||||
|
|
||||||
const SettingsApiKeys = lazy(() =>
|
const SettingsApiKeys = lazy(() =>
|
||||||
@ -388,7 +387,6 @@ export const SettingsRoutes = ({
|
|||||||
element={
|
element={
|
||||||
<SettingsProtectedRouteWrapper
|
<SettingsProtectedRouteWrapper
|
||||||
settingsPermission={SettingPermissionType.ROLES}
|
settingsPermission={SettingPermissionType.ROLES}
|
||||||
requiredFeatureFlag={FeatureFlagKey.IsPermissionsEnabled}
|
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -17,18 +17,12 @@ export const SettingsProtectedRouteWrapper = ({
|
|||||||
settingsPermission,
|
settingsPermission,
|
||||||
requiredFeatureFlag,
|
requiredFeatureFlag,
|
||||||
}: SettingsProtectedRouteWrapperProps) => {
|
}: SettingsProtectedRouteWrapperProps) => {
|
||||||
const isPermissionsEnabled = useIsFeatureEnabled(
|
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
|
||||||
);
|
|
||||||
const hasPermission = useHasSettingsPermission(settingsPermission);
|
const hasPermission = useHasSettingsPermission(settingsPermission);
|
||||||
const requiredFeatureFlagEnabled = useIsFeatureEnabled(
|
const requiredFeatureFlagEnabled = useIsFeatureEnabled(
|
||||||
requiredFeatureFlag || null,
|
requiredFeatureFlag || null,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if ((requiredFeatureFlag && !requiredFeatureFlagEnabled) || !hasPermission) {
|
||||||
(requiredFeatureFlag && !requiredFeatureFlagEnabled) ||
|
|
||||||
(!hasPermission && isPermissionsEnabled)
|
|
||||||
) {
|
|
||||||
return <Navigate to={getSettingsPath(SettingsPath.ProfilePage)} replace />;
|
return <Navigate to={getSettingsPath(SettingsPath.ProfilePage)} replace />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import { MutableSnapshot, RecoilRoot } from 'recoil';
|
import { MutableSnapshot, RecoilRoot } from 'recoil';
|
||||||
import {
|
import {
|
||||||
Billing,
|
Billing,
|
||||||
FeatureFlagKey,
|
|
||||||
OnboardingStatus,
|
OnboardingStatus,
|
||||||
SettingPermissionType,
|
SettingPermissionType,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
@ -52,12 +51,6 @@ jest.mock('@/settings/roles/hooks/useSettingsPermissionMap', () => ({
|
|||||||
useSettingsPermissionMap: jest.fn(),
|
useSettingsPermissionMap: jest.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('@/workspace/hooks/useFeatureFlagsMap', () => ({
|
|
||||||
useFeatureFlagsMap: () => ({
|
|
||||||
[FeatureFlagKey.IsPermissionsEnabled]: true,
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('useSettingsNavigationItems', () => {
|
describe('useSettingsNavigationItems', () => {
|
||||||
it('should hide workspace settings when no permissions', () => {
|
it('should hide workspace settings when no permissions', () => {
|
||||||
(useSettingsPermissionMap as jest.Mock).mockImplementation(() => ({
|
(useSettingsPermissionMap as jest.Mock).mockImplementation(() => ({
|
||||||
|
|||||||
@ -21,14 +21,12 @@ import {
|
|||||||
} from 'twenty-ui';
|
} from 'twenty-ui';
|
||||||
|
|
||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
|
||||||
|
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
import { billingState } from '@/client-config/states/billingState';
|
import { billingState } from '@/client-config/states/billingState';
|
||||||
import { labPublicFeatureFlagsState } from '@/client-config/states/labPublicFeatureFlagsState';
|
import { labPublicFeatureFlagsState } from '@/client-config/states/labPublicFeatureFlagsState';
|
||||||
import { useSettingsPermissionMap } from '@/settings/roles/hooks/useSettingsPermissionMap';
|
import { useSettingsPermissionMap } from '@/settings/roles/hooks/useSettingsPermissionMap';
|
||||||
import { NavigationDrawerItemIndentationLevel } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
import { NavigationDrawerItemIndentationLevel } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
||||||
import { useFeatureFlagsMap } from '@/workspace/hooks/useFeatureFlagsMap';
|
|
||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { SettingPermissionType } from '~/generated/graphql';
|
import { SettingPermissionType } from '~/generated/graphql';
|
||||||
@ -63,7 +61,6 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
|||||||
false;
|
false;
|
||||||
const labPublicFeatureFlags = useRecoilValue(labPublicFeatureFlagsState);
|
const labPublicFeatureFlags = useRecoilValue(labPublicFeatureFlagsState);
|
||||||
|
|
||||||
const featureFlags = useFeatureFlagsMap();
|
|
||||||
const permissionMap = useSettingsPermissionMap();
|
const permissionMap = useSettingsPermissionMap();
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -120,9 +117,7 @@ const useSettingsNavigationItems = (): SettingsNavigationSection[] => {
|
|||||||
label: t`Roles`,
|
label: t`Roles`,
|
||||||
path: SettingsPath.Roles,
|
path: SettingsPath.Roles,
|
||||||
Icon: IconLock,
|
Icon: IconLock,
|
||||||
isHidden:
|
isHidden: !permissionMap[SettingPermissionType.ROLES],
|
||||||
!featureFlags[FeatureFlagKey.IsPermissionsEnabled] ||
|
|
||||||
!permissionMap[SettingPermissionType.ROLES],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t`Billing`,
|
label: t`Billing`,
|
||||||
|
|||||||
@ -1,19 +1,10 @@
|
|||||||
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
|
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
|
||||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
import { PermissionsOnAllObjectRecords } from 'twenty-shared/constants';
|
import { PermissionsOnAllObjectRecords } from 'twenty-shared/constants';
|
||||||
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
export const useHasObjectReadOnlyPermission = () => {
|
export const useHasObjectReadOnlyPermission = () => {
|
||||||
const currentUserWorkspace = useRecoilValue(currentUserWorkspaceState);
|
const currentUserWorkspace = useRecoilValue(currentUserWorkspaceState);
|
||||||
const isPermissionEnabled = useIsFeatureEnabled(
|
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isPermissionEnabled) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDefined(currentUserWorkspace?.objectRecordsPermissions)) {
|
if (!isDefined(currentUserWorkspace?.objectRecordsPermissions)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
|
import { currentUserWorkspaceState } from '@/auth/states/currentUserWorkspaceState';
|
||||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
|
||||||
import { SettingPermissionType } from '~/generated/graphql';
|
import { SettingPermissionType } from '~/generated/graphql';
|
||||||
import { buildRecordFromKeysWithSameValue } from '~/utils/array/buildRecordFromKeysWithSameValue';
|
import { buildRecordFromKeysWithSameValue } from '~/utils/array/buildRecordFromKeysWithSameValue';
|
||||||
|
|
||||||
@ -11,16 +9,12 @@ export const useSettingsPermissionMap = (): Record<
|
|||||||
> => {
|
> => {
|
||||||
const currentUserWorkspace = useRecoilValue(currentUserWorkspaceState);
|
const currentUserWorkspace = useRecoilValue(currentUserWorkspaceState);
|
||||||
|
|
||||||
const isPermissionEnabled = useIsFeatureEnabled(
|
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentUserWorkspaceSettingsPermissions =
|
const currentUserWorkspaceSettingsPermissions =
|
||||||
currentUserWorkspace?.settingsPermissions;
|
currentUserWorkspace?.settingsPermissions;
|
||||||
|
|
||||||
const initialPermissions = buildRecordFromKeysWithSameValue(
|
const initialPermissions = buildRecordFromKeysWithSameValue(
|
||||||
Object.values(SettingPermissionType),
|
Object.values(SettingPermissionType),
|
||||||
!isPermissionEnabled,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!currentUserWorkspaceSettingsPermissions) {
|
if (!currentUserWorkspaceSettingsPermissions) {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { DataSource } from 'typeorm';
|
|
||||||
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
|
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
import { extractVersionMajorMinorPatch } from 'src/utils/version/extract-version-major-minor-patch';
|
import { extractVersionMajorMinorPatch } from 'src/utils/version/extract-version-major-minor-patch';
|
||||||
@ -46,7 +46,7 @@ export const seedWorkspaces = async ({
|
|||||||
subdomain: 'apple',
|
subdomain: 'apple',
|
||||||
inviteHash: 'apple.dev-invite-hash',
|
inviteHash: 'apple.dev-invite-hash',
|
||||||
logo: 'https://twentyhq.github.io/placeholder-images/workspaces/apple-logo.png',
|
logo: 'https://twentyhq.github.io/placeholder-images/workspaces/apple-logo.png',
|
||||||
activationStatus: WorkspaceActivationStatus.ACTIVE,
|
activationStatus: WorkspaceActivationStatus.PENDING_CREATION, // will be set to active after default role creation
|
||||||
version: version,
|
version: version,
|
||||||
},
|
},
|
||||||
[SEED_ACME_WORKSPACE_ID]: {
|
[SEED_ACME_WORKSPACE_ID]: {
|
||||||
@ -55,7 +55,7 @@ export const seedWorkspaces = async ({
|
|||||||
subdomain: 'acme',
|
subdomain: 'acme',
|
||||||
inviteHash: 'acme.dev-invite-hash',
|
inviteHash: 'acme.dev-invite-hash',
|
||||||
logo: 'https://logos-world.net/wp-content/uploads/2022/05/Acme-Logo-700x394.png',
|
logo: 'https://logos-world.net/wp-content/uploads/2022/05/Acme-Logo-700x394.png',
|
||||||
activationStatus: WorkspaceActivationStatus.ACTIVE,
|
activationStatus: WorkspaceActivationStatus.PENDING_CREATION, // will be set to active after default role creation
|
||||||
version: version,
|
version: version,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -87,17 +87,9 @@ export abstract class GraphqlQueryBaseResolverService<
|
|||||||
authContext.workspace.id,
|
authContext.workspace.id,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (objectMetadataItemWithFieldMaps.isSystem === true) {
|
||||||
featureFlagsMap[FeatureFlagKey.IsPermissionsEnabled] &&
|
|
||||||
objectMetadataItemWithFieldMaps.isSystem === true
|
|
||||||
) {
|
|
||||||
await this.validateSystemObjectPermissionsOrThrow(options);
|
await this.validateSystemObjectPermissionsOrThrow(options);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (
|
|
||||||
featureFlagsMap[FeatureFlagKey.IsPermissionsEnabled] &&
|
|
||||||
!objectMetadataItemWithFieldMaps.isSystem
|
|
||||||
) {
|
|
||||||
await this.validateObjectRecordPermissionsOrThrow({
|
await this.validateObjectRecordPermissionsOrThrow({
|
||||||
operationName,
|
operationName,
|
||||||
options,
|
options,
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import { BillingSubscriptionService } from 'src/engine/core-modules/billing/serv
|
|||||||
import { BillingService } from 'src/engine/core-modules/billing/services/billing.service';
|
import { BillingService } from 'src/engine/core-modules/billing/services/billing.service';
|
||||||
import { BillingPortalCheckoutSessionParameters } from 'src/engine/core-modules/billing/types/billing-portal-checkout-session-parameters.type';
|
import { BillingPortalCheckoutSessionParameters } from 'src/engine/core-modules/billing/types/billing-portal-checkout-session-parameters.type';
|
||||||
import { formatBillingDatabaseProductToGraphqlDTO } from 'src/engine/core-modules/billing/utils/format-database-product-to-graphql-dto.util';
|
import { formatBillingDatabaseProductToGraphqlDTO } from 'src/engine/core-modules/billing/utils/format-database-product-to-graphql-dto.util';
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
@ -140,15 +139,6 @@ export class BillingResolver {
|
|||||||
userWorkspaceId: string;
|
userWorkspaceId: string;
|
||||||
isExecutedByApiKey: boolean;
|
isExecutedByApiKey: boolean;
|
||||||
}) {
|
}) {
|
||||||
const isPermissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isPermissionsEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
await this.billingService.isSubscriptionIncompleteOnboardingStatus(
|
await this.billingService.isSubscriptionIncompleteOnboardingStatus(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
|||||||
@ -9,9 +9,7 @@ type FeatureFlagMetadata = {
|
|||||||
export type PublicFeatureFlag = {
|
export type PublicFeatureFlag = {
|
||||||
key: Extract<
|
key: Extract<
|
||||||
FeatureFlagKey,
|
FeatureFlagKey,
|
||||||
| FeatureFlagKey.IsWorkflowEnabled
|
FeatureFlagKey.IsWorkflowEnabled | FeatureFlagKey.IsCustomDomainEnabled
|
||||||
| FeatureFlagKey.IsPermissionsEnabled
|
|
||||||
| FeatureFlagKey.IsCustomDomainEnabled
|
|
||||||
>;
|
>;
|
||||||
metadata: FeatureFlagMetadata;
|
metadata: FeatureFlagMetadata;
|
||||||
};
|
};
|
||||||
@ -25,15 +23,6 @@ export const PUBLIC_FEATURE_FLAGS: PublicFeatureFlag[] = [
|
|||||||
imagePath: 'https://twenty.com/images/lab/is-workflow-enabled.png',
|
imagePath: 'https://twenty.com/images/lab/is-workflow-enabled.png',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: FeatureFlagKey.IsPermissionsEnabled,
|
|
||||||
metadata: {
|
|
||||||
label: 'Permissions V1',
|
|
||||||
description:
|
|
||||||
'Role-based access control system for workspace security management (Admin/Member)',
|
|
||||||
imagePath: 'https://twenty.com/images/lab/is-permissions-enabled.png',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...(process.env.CLOUDFLARE_API_KEY
|
...(process.env.CLOUDFLARE_API_KEY
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -12,7 +12,6 @@ export enum FeatureFlagKey {
|
|||||||
IsCustomDomainEnabled = 'IS_CUSTOM_DOMAIN_ENABLED',
|
IsCustomDomainEnabled = 'IS_CUSTOM_DOMAIN_ENABLED',
|
||||||
IsApprovedAccessDomainsEnabled = 'IS_APPROVED_ACCESS_DOMAINS_ENABLED',
|
IsApprovedAccessDomainsEnabled = 'IS_APPROVED_ACCESS_DOMAINS_ENABLED',
|
||||||
IsNewRelationEnabled = 'IS_NEW_RELATION_ENABLED',
|
IsNewRelationEnabled = 'IS_NEW_RELATION_ENABLED',
|
||||||
IsPermissionsEnabled = 'IS_PERMISSIONS_ENABLED',
|
|
||||||
IsWorkflowFormActionEnabled = 'IS_WORKFLOW_FORM_ACTION_ENABLED',
|
IsWorkflowFormActionEnabled = 'IS_WORKFLOW_FORM_ACTION_ENABLED',
|
||||||
IsPermissionsV2Enabled = 'IS_PERMISSIONS_V2_ENABLED',
|
IsPermissionsV2Enabled = 'IS_PERMISSIONS_V2_ENABLED',
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,8 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
|
||||||
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
||||||
import { Repository } from 'typeorm';
|
|
||||||
import { isWorkspaceActiveOrSuspended } from 'twenty-shared/workspace';
|
import { isWorkspaceActiveOrSuspended } from 'twenty-shared/workspace';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||||
@ -12,7 +12,6 @@ import {
|
|||||||
AuthException,
|
AuthException,
|
||||||
AuthExceptionCode,
|
AuthExceptionCode,
|
||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
} from 'src/engine/core-modules/auth/auth.exception';
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||||
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
||||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
@ -97,16 +96,11 @@ export class UserService extends TypeOrmQueryService<User> {
|
|||||||
const workspaceDataSource =
|
const workspaceDataSource =
|
||||||
await this.typeORMService.connectToDataSource(dataSourceMetadata);
|
await this.typeORMService.connectToDataSource(dataSourceMetadata);
|
||||||
|
|
||||||
const isPermissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
const workspaceMembers = await workspaceDataSource?.query(
|
const workspaceMembers = await workspaceDataSource?.query(
|
||||||
`SELECT * FROM ${dataSourceMetadata.schema}."workspaceMember"`,
|
`SELECT * FROM ${dataSourceMetadata.schema}."workspaceMember"`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isPermissionsEnabled && workspaceMembers.length > 1) {
|
if (workspaceMembers.length > 1) {
|
||||||
const userWorkspace =
|
const userWorkspace =
|
||||||
await this.userWorkspaceService.getUserWorkspaceForUserOrThrow({
|
await this.userWorkspaceService.getUserWorkspaceForUserOrThrow({
|
||||||
userId,
|
userId,
|
||||||
|
|||||||
@ -27,8 +27,6 @@ import {
|
|||||||
} from 'src/engine/core-modules/auth/auth.exception';
|
} from 'src/engine/core-modules/auth/auth.exception';
|
||||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
|
||||||
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
|
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
|
||||||
import { FileService } from 'src/engine/core-modules/file/services/file.service';
|
import { FileService } from 'src/engine/core-modules/file/services/file.service';
|
||||||
import { OnboardingStatus } from 'src/engine/core-modules/onboarding/enums/onboarding-status.enum';
|
import { OnboardingStatus } from 'src/engine/core-modules/onboarding/enums/onboarding-status.enum';
|
||||||
@ -83,7 +81,6 @@ export class UserResolver {
|
|||||||
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
|
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
|
||||||
private readonly userRoleService: UserRoleService,
|
private readonly userRoleService: UserRoleService,
|
||||||
private readonly permissionsService: PermissionsService,
|
private readonly permissionsService: PermissionsService,
|
||||||
private readonly featureFlagService: FeatureFlagService,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Query(() => User)
|
@Query(() => User)
|
||||||
@ -103,38 +100,31 @@ export class UserResolver {
|
|||||||
new AuthException('User not found', AuthExceptionCode.USER_NOT_FOUND),
|
new AuthException('User not found', AuthExceptionCode.USER_NOT_FOUND),
|
||||||
);
|
);
|
||||||
|
|
||||||
const permissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
const currentUserWorkspace = user.workspaces.find(
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
(userWorkspace) => userWorkspace.workspace.id === workspace.id,
|
||||||
workspace.id,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (permissionsEnabled === true) {
|
if (!currentUserWorkspace) {
|
||||||
const currentUserWorkspace = user.workspaces.find(
|
throw new Error('Current user workspace not found');
|
||||||
(userWorkspace) => userWorkspace.workspace.id === workspace.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!currentUserWorkspace) {
|
|
||||||
throw new Error('Current user workspace not found');
|
|
||||||
}
|
|
||||||
const { settingsPermissions, objectRecordsPermissions } =
|
|
||||||
await this.permissionsService.getUserWorkspacePermissions({
|
|
||||||
userWorkspaceId: currentUserWorkspace.id,
|
|
||||||
workspaceId: workspace.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
const grantedSettingsPermissions: SettingPermissionType[] = (
|
|
||||||
Object.keys(settingsPermissions) as SettingPermissionType[]
|
|
||||||
).filter((feature) => settingsPermissions[feature] === true);
|
|
||||||
|
|
||||||
const grantedObjectRecordsPermissions = (
|
|
||||||
Object.keys(objectRecordsPermissions) as PermissionsOnAllObjectRecords[]
|
|
||||||
).filter((permission) => objectRecordsPermissions[permission] === true);
|
|
||||||
|
|
||||||
currentUserWorkspace.settingsPermissions = grantedSettingsPermissions;
|
|
||||||
currentUserWorkspace.objectRecordsPermissions =
|
|
||||||
grantedObjectRecordsPermissions;
|
|
||||||
user.currentUserWorkspace = currentUserWorkspace;
|
|
||||||
}
|
}
|
||||||
|
const { settingsPermissions, objectRecordsPermissions } =
|
||||||
|
await this.permissionsService.getUserWorkspacePermissions({
|
||||||
|
userWorkspaceId: currentUserWorkspace.id,
|
||||||
|
workspaceId: workspace.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const grantedSettingsPermissions: SettingPermissionType[] = (
|
||||||
|
Object.keys(settingsPermissions) as SettingPermissionType[]
|
||||||
|
).filter((feature) => settingsPermissions[feature] === true);
|
||||||
|
|
||||||
|
const grantedObjectRecordsPermissions = (
|
||||||
|
Object.keys(objectRecordsPermissions) as PermissionsOnAllObjectRecords[]
|
||||||
|
).filter((permission) => objectRecordsPermissions[permission] === true);
|
||||||
|
|
||||||
|
currentUserWorkspace.settingsPermissions = grantedSettingsPermissions;
|
||||||
|
currentUserWorkspace.objectRecordsPermissions =
|
||||||
|
grantedObjectRecordsPermissions;
|
||||||
|
user.currentUserWorkspace = currentUserWorkspace;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
@ -202,37 +192,31 @@ export class UserResolver {
|
|||||||
|
|
||||||
const workspaceMembers: WorkspaceMember[] = [];
|
const workspaceMembers: WorkspaceMember[] = [];
|
||||||
|
|
||||||
const permissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
|
||||||
workspace.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
let userWorkspacesByUserId = new Map<string, UserWorkspace>();
|
let userWorkspacesByUserId = new Map<string, UserWorkspace>();
|
||||||
let rolesByUserWorkspaces = new Map<string, RoleDTO[]>();
|
let rolesByUserWorkspaces = new Map<string, RoleDTO[]>();
|
||||||
|
|
||||||
if (permissionsEnabled === true) {
|
const userWorkspaces = await this.userWorkspaceRepository.find({
|
||||||
const userWorkspaces = await this.userWorkspaceRepository.find({
|
where: {
|
||||||
where: {
|
userId: In(workspaceMemberEntities.map((entity) => entity.userId)),
|
||||||
userId: In(workspaceMemberEntities.map((entity) => entity.userId)),
|
workspaceId: workspace.id,
|
||||||
workspaceId: workspace.id,
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
userWorkspacesByUserId = new Map(
|
userWorkspacesByUserId = new Map(
|
||||||
userWorkspaces.map((userWorkspace) => [
|
userWorkspaces.map((userWorkspace) => [
|
||||||
userWorkspace.userId,
|
userWorkspace.userId,
|
||||||
userWorkspace,
|
userWorkspace,
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
rolesByUserWorkspaces =
|
rolesByUserWorkspaces = await this.userRoleService.getRolesByUserWorkspaces(
|
||||||
await this.userRoleService.getRolesByUserWorkspaces({
|
{
|
||||||
userWorkspaceIds: userWorkspaces.map(
|
userWorkspaceIds: userWorkspaces.map(
|
||||||
(userWorkspace) => userWorkspace.id,
|
(userWorkspace) => userWorkspace.id,
|
||||||
),
|
),
|
||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
});
|
},
|
||||||
}
|
);
|
||||||
|
|
||||||
for (const workspaceMemberEntity of workspaceMemberEntities) {
|
for (const workspaceMemberEntity of workspaceMemberEntities) {
|
||||||
if (workspaceMemberEntity.avatarUrl) {
|
if (workspaceMemberEntity.avatarUrl) {
|
||||||
@ -246,39 +230,37 @@ export class UserResolver {
|
|||||||
|
|
||||||
const workspaceMember = workspaceMemberEntity as WorkspaceMember;
|
const workspaceMember = workspaceMemberEntity as WorkspaceMember;
|
||||||
|
|
||||||
if (permissionsEnabled === true) {
|
const userWorkspace = userWorkspacesByUserId.get(
|
||||||
const userWorkspace = userWorkspacesByUserId.get(
|
workspaceMemberEntity.userId,
|
||||||
workspaceMemberEntity.userId,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (!userWorkspace) {
|
if (!userWorkspace) {
|
||||||
throw new Error('User workspace not found');
|
throw new Error('User workspace not found');
|
||||||
}
|
|
||||||
|
|
||||||
workspaceMember.userWorkspaceId = userWorkspace.id;
|
|
||||||
|
|
||||||
const workspaceMemberRoles = (
|
|
||||||
rolesByUserWorkspaces.get(userWorkspace.id) ?? []
|
|
||||||
).map((roleEntity) => {
|
|
||||||
return {
|
|
||||||
id: roleEntity.id,
|
|
||||||
label: roleEntity.label,
|
|
||||||
canUpdateAllSettings: roleEntity.canUpdateAllSettings,
|
|
||||||
description: roleEntity.description,
|
|
||||||
icon: roleEntity.icon,
|
|
||||||
isEditable: roleEntity.isEditable,
|
|
||||||
userWorkspaceRoles: roleEntity.userWorkspaceRoles,
|
|
||||||
canReadAllObjectRecords: roleEntity.canReadAllObjectRecords,
|
|
||||||
canUpdateAllObjectRecords: roleEntity.canUpdateAllObjectRecords,
|
|
||||||
canSoftDeleteAllObjectRecords:
|
|
||||||
roleEntity.canSoftDeleteAllObjectRecords,
|
|
||||||
canDestroyAllObjectRecords: roleEntity.canDestroyAllObjectRecords,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
workspaceMember.roles = workspaceMemberRoles;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workspaceMember.userWorkspaceId = userWorkspace.id;
|
||||||
|
|
||||||
|
const workspaceMemberRoles = (
|
||||||
|
rolesByUserWorkspaces.get(userWorkspace.id) ?? []
|
||||||
|
).map((roleEntity) => {
|
||||||
|
return {
|
||||||
|
id: roleEntity.id,
|
||||||
|
label: roleEntity.label,
|
||||||
|
canUpdateAllSettings: roleEntity.canUpdateAllSettings,
|
||||||
|
description: roleEntity.description,
|
||||||
|
icon: roleEntity.icon,
|
||||||
|
isEditable: roleEntity.isEditable,
|
||||||
|
userWorkspaceRoles: roleEntity.userWorkspaceRoles,
|
||||||
|
canReadAllObjectRecords: roleEntity.canReadAllObjectRecords,
|
||||||
|
canUpdateAllObjectRecords: roleEntity.canUpdateAllObjectRecords,
|
||||||
|
canSoftDeleteAllObjectRecords:
|
||||||
|
roleEntity.canSoftDeleteAllObjectRecords,
|
||||||
|
canDestroyAllObjectRecords: roleEntity.canDestroyAllObjectRecords,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
workspaceMember.roles = workspaceMemberRoles;
|
||||||
|
|
||||||
workspaceMembers.push(workspaceMember);
|
workspaceMembers.push(workspaceMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import { CustomDomainService } from 'src/engine/core-modules/domain-manager/serv
|
|||||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||||
import {
|
import {
|
||||||
FileWorkspaceFolderDeletionJob,
|
FileWorkspaceFolderDeletionJob,
|
||||||
@ -154,26 +153,19 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
|
|||||||
|
|
||||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||||
|
|
||||||
const permissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
await this.validateSecurityPermissions({
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
payload,
|
||||||
workspace.id,
|
userWorkspaceId,
|
||||||
);
|
workspaceId: workspace.id,
|
||||||
|
apiKey,
|
||||||
|
});
|
||||||
|
|
||||||
if (permissionsEnabled) {
|
await this.validateWorkspacePermissions({
|
||||||
await this.validateSecurityPermissions({
|
payload,
|
||||||
payload,
|
userWorkspaceId,
|
||||||
userWorkspaceId,
|
workspaceId: workspace.id,
|
||||||
workspaceId: workspace.id,
|
apiKey,
|
||||||
apiKey,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
await this.validateWorkspacePermissions({
|
|
||||||
payload,
|
|
||||||
userWorkspaceId,
|
|
||||||
workspaceId: workspace.id,
|
|
||||||
apiKey,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (payload.subdomain && workspace.subdomain !== payload.subdomain) {
|
if (payload.subdomain && workspace.subdomain !== payload.subdomain) {
|
||||||
await this.validateSubdomainUpdate(payload.subdomain);
|
await this.validateSubdomainUpdate(payload.subdomain);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||||
|
|
||||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||||
|
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
|
||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
CreateDateColumn,
|
CreateDateColumn,
|
||||||
@ -11,7 +12,6 @@ import {
|
|||||||
Relation,
|
Relation,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
|
|
||||||
|
|
||||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||||
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
|
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
|
||||||
|
|||||||
@ -9,8 +9,6 @@ import { GqlExecutionContext } from '@nestjs/graphql';
|
|||||||
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
|
||||||
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
|
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
|
||||||
import {
|
import {
|
||||||
PermissionsException,
|
PermissionsException,
|
||||||
@ -24,24 +22,11 @@ export const SettingsPermissionsGuard = (
|
|||||||
): Type<CanActivate> => {
|
): Type<CanActivate> => {
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class SettingsPermissionsMixin implements CanActivate {
|
class SettingsPermissionsMixin implements CanActivate {
|
||||||
constructor(
|
constructor(private readonly permissionsService: PermissionsService) {}
|
||||||
private readonly featureFlagService: FeatureFlagService,
|
|
||||||
private readonly permissionsService: PermissionsService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
const ctx = GqlExecutionContext.create(context);
|
const ctx = GqlExecutionContext.create(context);
|
||||||
const workspaceId = ctx.getContext().req.workspace.id;
|
const workspaceId = ctx.getContext().req.workspace.id;
|
||||||
|
|
||||||
const permissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
|
||||||
FeatureFlagKey.IsPermissionsEnabled,
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!permissionsEnabled) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const userWorkspaceId = ctx.getContext().req.userWorkspaceId;
|
const userWorkspaceId = ctx.getContext().req.userWorkspaceId;
|
||||||
|
|
||||||
const hasPermission =
|
const hasPermission =
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Injectable, Logger } from '@nestjs/common';
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
import { DEV_SEED_USER_WORKSPACE_IDS } from 'src/database/typeorm-seeds/core/user-workspaces';
|
import { DEV_SEED_USER_WORKSPACE_IDS } from 'src/database/typeorm-seeds/core/user-workspaces';
|
||||||
@ -8,7 +9,6 @@ import {
|
|||||||
SEED_ACME_WORKSPACE_ID,
|
SEED_ACME_WORKSPACE_ID,
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
SEED_APPLE_WORKSPACE_ID,
|
||||||
} from 'src/database/typeorm-seeds/core/workspaces';
|
} from 'src/database/typeorm-seeds/core/workspaces';
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
@ -315,21 +315,16 @@ export class WorkspaceManagerService {
|
|||||||
roleId: adminRole.id,
|
roleId: adminRole.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.roleService.createMemberRole({
|
const memberRole = await this.roleService.createMemberRole({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Temporary - after permissions are rolled-out we will set member role as the default role
|
|
||||||
await this.workspaceRepository.update(workspaceId, {
|
await this.workspaceRepository.update(workspaceId, {
|
||||||
defaultRoleId: adminRole.id,
|
defaultRoleId: memberRole.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initPermissionsDev(workspaceId: string) {
|
private async initPermissionsDev(workspaceId: string) {
|
||||||
await this.featureFlagService.enableFeatureFlags(
|
|
||||||
[FeatureFlagKey.IsPermissionsEnabled],
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
const adminRole = await this.roleService.createAdminRole({
|
const adminRole = await this.roleService.createAdminRole({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
});
|
});
|
||||||
@ -369,6 +364,7 @@ export class WorkspaceManagerService {
|
|||||||
|
|
||||||
await this.workspaceRepository.update(workspaceId, {
|
await this.workspaceRepository.update(workspaceId, {
|
||||||
defaultRoleId: memberRole.id,
|
defaultRoleId: memberRole.id,
|
||||||
|
activationStatus: WorkspaceActivationStatus.ACTIVE,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (memberUserWorkspaceId) {
|
if (memberUserWorkspaceId) {
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||||
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
|
import { SettingPermissionType } from 'src/engine/metadata-modules/permissions/constants/setting-permission-type.constants';
|
||||||
import {
|
import {
|
||||||
@ -33,16 +32,6 @@ export class WorkspaceMemberPreQueryHookService {
|
|||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
apiKey?: ApiKeyWorkspaceEntity | null;
|
apiKey?: ApiKeyWorkspaceEntity | null;
|
||||||
}) {
|
}) {
|
||||||
const featureFlagsMap =
|
|
||||||
await this.featureFlagService.getWorkspaceFeatureFlagsMap(workspaceId);
|
|
||||||
|
|
||||||
const isPermissionsEnabled =
|
|
||||||
featureFlagsMap[FeatureFlagKey.IsPermissionsEnabled];
|
|
||||||
|
|
||||||
if (!isPermissionsEnabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDefined(apiKey)) {
|
if (isDefined(apiKey)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,33 +4,11 @@ import { PERSON_GQL_FIELDS } from 'test/integration/constants/person-gql-fields.
|
|||||||
import { createManyOperationFactory } from 'test/integration/graphql/utils/create-many-operation-factory.util';
|
import { createManyOperationFactory } from 'test/integration/graphql/utils/create-many-operation-factory.util';
|
||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
describe('createManyObjectRecordsPermissions', () => {
|
describe('createManyObjectRecordsPermissions', () => {
|
||||||
beforeAll(async () => {
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const graphqlOperation = createManyOperationFactory({
|
const graphqlOperation = createManyOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
|
|||||||
@ -4,33 +4,11 @@ import { PERSON_GQL_FIELDS } from 'test/integration/constants/person-gql-fields.
|
|||||||
import { createOneOperationFactory } from 'test/integration/graphql/utils/create-one-operation-factory.util';
|
import { createOneOperationFactory } from 'test/integration/graphql/utils/create-one-operation-factory.util';
|
||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
describe('createOneObjectRecordsPermissions', () => {
|
describe('createOneObjectRecordsPermissions', () => {
|
||||||
beforeAll(async () => {
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const graphqlOperation = createOneOperationFactory({
|
const graphqlOperation = createOneOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
|
|||||||
@ -5,33 +5,11 @@ import { createManyOperationFactory } from 'test/integration/graphql/utils/creat
|
|||||||
import { deleteManyOperationFactory } from 'test/integration/graphql/utils/delete-many-operation-factory.util';
|
import { deleteManyOperationFactory } from 'test/integration/graphql/utils/delete-many-operation-factory.util';
|
||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
describe('deleteManyObjectRecordsPermissions', () => {
|
describe('deleteManyObjectRecordsPermissions', () => {
|
||||||
beforeAll(async () => {
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const graphqlOperation = deleteManyOperationFactory({
|
const graphqlOperation = deleteManyOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
|
|||||||
@ -5,9 +5,7 @@ import { createOneOperationFactory } from 'test/integration/graphql/utils/create
|
|||||||
import { deleteOneOperationFactory } from 'test/integration/graphql/utils/delete-one-operation-factory.util';
|
import { deleteOneOperationFactory } from 'test/integration/graphql/utils/delete-one-operation-factory.util';
|
||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
@ -15,15 +13,7 @@ describe('deleteOneObjectRecordsPermissions', () => {
|
|||||||
const personId = randomUUID();
|
const personId = randomUUID();
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
const createOnePersonRecordOperation = createOneOperationFactory({
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
|
|
||||||
const createGraphqlOperation = createOneOperationFactory({
|
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
gqlFields: PERSON_GQL_FIELDS,
|
gqlFields: PERSON_GQL_FIELDS,
|
||||||
data: {
|
data: {
|
||||||
@ -31,17 +21,7 @@ describe('deleteOneObjectRecordsPermissions', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(createGraphqlOperation);
|
await makeGraphqlAPIRequest(createOnePersonRecordOperation);
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
|
|||||||
@ -5,33 +5,11 @@ import { createManyOperationFactory } from 'test/integration/graphql/utils/creat
|
|||||||
import { destroyManyOperationFactory } from 'test/integration/graphql/utils/destroy-many-operation-factory.util';
|
import { destroyManyOperationFactory } from 'test/integration/graphql/utils/destroy-many-operation-factory.util';
|
||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
describe('destroyManyObjectRecordsPermissions', () => {
|
describe('destroyManyObjectRecordsPermissions', () => {
|
||||||
beforeAll(async () => {
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const graphqlOperation = destroyManyOperationFactory({
|
const graphqlOperation = destroyManyOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
|
|||||||
@ -5,9 +5,7 @@ import { createOneOperationFactory } from 'test/integration/graphql/utils/create
|
|||||||
import { destroyOneOperationFactory } from 'test/integration/graphql/utils/destroy-one-operation-factory.util';
|
import { destroyOneOperationFactory } from 'test/integration/graphql/utils/destroy-one-operation-factory.util';
|
||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
@ -15,14 +13,6 @@ describe('destroyOneObjectRecordsPermissions', () => {
|
|||||||
const personId = randomUUID();
|
const personId = randomUUID();
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
|
|
||||||
const createGraphqlOperation = createOneOperationFactory({
|
const createGraphqlOperation = createOneOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
gqlFields: PERSON_GQL_FIELDS,
|
gqlFields: PERSON_GQL_FIELDS,
|
||||||
@ -34,16 +24,6 @@ describe('destroyOneObjectRecordsPermissions', () => {
|
|||||||
await makeGraphqlAPIRequest(createGraphqlOperation);
|
await makeGraphqlAPIRequest(createGraphqlOperation);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const personId = randomUUID();
|
const personId = randomUUID();
|
||||||
const graphqlOperation = destroyOneOperationFactory({
|
const graphqlOperation = destroyOneOperationFactory({
|
||||||
|
|||||||
@ -6,9 +6,7 @@ import { deleteManyOperationFactory } from 'test/integration/graphql/utils/delet
|
|||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { restoreManyOperationFactory } from 'test/integration/graphql/utils/restore-many-operation-factory.util';
|
import { restoreManyOperationFactory } from 'test/integration/graphql/utils/restore-many-operation-factory.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
@ -17,14 +15,6 @@ describe('restoreManyObjectRecordsPermissions', () => {
|
|||||||
const personId2 = randomUUID();
|
const personId2 = randomUUID();
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
|
|
||||||
// Create people
|
// Create people
|
||||||
const createGraphqlOperation = createManyOperationFactory({
|
const createGraphqlOperation = createManyOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
@ -57,16 +47,6 @@ describe('restoreManyObjectRecordsPermissions', () => {
|
|||||||
await makeGraphqlAPIRequest(deleteGraphqlOperation);
|
await makeGraphqlAPIRequest(deleteGraphqlOperation);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const graphqlOperation = restoreManyOperationFactory({
|
const graphqlOperation = restoreManyOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
|
|||||||
@ -6,9 +6,7 @@ import { deleteOneOperationFactory } from 'test/integration/graphql/utils/delete
|
|||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { restoreOneOperationFactory } from 'test/integration/graphql/utils/restore-one-operation-factory.util';
|
import { restoreOneOperationFactory } from 'test/integration/graphql/utils/restore-one-operation-factory.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
@ -16,14 +14,6 @@ describe('restoreOneObjectRecordsPermissions', () => {
|
|||||||
const personId = randomUUID();
|
const personId = randomUUID();
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
|
|
||||||
// Create a person
|
// Create a person
|
||||||
const createGraphqlOperation = createOneOperationFactory({
|
const createGraphqlOperation = createOneOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
@ -45,16 +35,6 @@ describe('restoreOneObjectRecordsPermissions', () => {
|
|||||||
await makeGraphqlAPIRequest(deleteGraphqlOperation);
|
await makeGraphqlAPIRequest(deleteGraphqlOperation);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const graphqlOperation = restoreOneOperationFactory({
|
const graphqlOperation = restoreOneOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
|
|||||||
@ -4,10 +4,8 @@ import { PERSON_GQL_FIELDS } from 'test/integration/constants/person-gql-fields.
|
|||||||
import { createManyOperationFactory } from 'test/integration/graphql/utils/create-many-operation-factory.util';
|
import { createManyOperationFactory } from 'test/integration/graphql/utils/create-many-operation-factory.util';
|
||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
import { updateManyOperationFactory } from 'test/integration/graphql/utils/update-many-operation-factory.util';
|
import { updateManyOperationFactory } from 'test/integration/graphql/utils/update-many-operation-factory.util';
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
@ -16,14 +14,6 @@ describe('updateManyObjectRecordsPermissions', () => {
|
|||||||
const personId2 = randomUUID();
|
const personId2 = randomUUID();
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
|
|
||||||
const createGraphqlOperation = createManyOperationFactory({
|
const createGraphqlOperation = createManyOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
objectMetadataPluralName: 'people',
|
objectMetadataPluralName: 'people',
|
||||||
@ -41,16 +31,6 @@ describe('updateManyObjectRecordsPermissions', () => {
|
|||||||
await makeGraphqlAPIRequest(createGraphqlOperation);
|
await makeGraphqlAPIRequest(createGraphqlOperation);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const graphqlOperation = updateManyOperationFactory({
|
const graphqlOperation = updateManyOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
|
|||||||
@ -4,10 +4,8 @@ import { PERSON_GQL_FIELDS } from 'test/integration/constants/person-gql-fields.
|
|||||||
import { createOneOperationFactory } from 'test/integration/graphql/utils/create-one-operation-factory.util';
|
import { createOneOperationFactory } from 'test/integration/graphql/utils/create-one-operation-factory.util';
|
||||||
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
import { makeGraphqlAPIRequestWithGuestRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-guest-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
|
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
@ -15,14 +13,6 @@ describe('updateOneObjectRecordsPermissions', () => {
|
|||||||
const personId = randomUUID();
|
const personId = randomUUID();
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
|
|
||||||
const createPersonOperation = createOneOperationFactory({
|
const createPersonOperation = createOneOperationFactory({
|
||||||
objectMetadataSingularName: 'person',
|
objectMetadataSingularName: 'person',
|
||||||
gqlFields: PERSON_GQL_FIELDS,
|
gqlFields: PERSON_GQL_FIELDS,
|
||||||
@ -35,16 +25,6 @@ describe('updateOneObjectRecordsPermissions', () => {
|
|||||||
await makeGraphqlAPIRequest(createPersonOperation);
|
await makeGraphqlAPIRequest(createPersonOperation);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
it('should throw a permission error when user does not have permission (guest role)', async () => {
|
||||||
const personId = randomUUID();
|
const personId = randomUUID();
|
||||||
const graphqlOperation = updateOneOperationFactory({
|
const graphqlOperation = updateOneOperationFactory({
|
||||||
|
|||||||
@ -1,33 +1,11 @@
|
|||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
const client = request(`http://localhost:${APP_PORT}`);
|
const client = request(`http://localhost:${APP_PORT}`);
|
||||||
|
|
||||||
describe('api key and webhooks permissions', () => {
|
describe('api key and webhooks permissions', () => {
|
||||||
beforeAll(async () => {
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
describe('generateApiKeyToken', () => {
|
describe('generateApiKeyToken', () => {
|
||||||
it('should throw a permission error when user does not have permission (member role)', async () => {
|
it('should throw a permission error when user does not have permission (member role)', async () => {
|
||||||
const queryData = {
|
const queryData = {
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
import { createCustomTextFieldMetadata } from 'test/integration/metadata/suites/field-metadata/utils/create-custom-text-field-metadata.util';
|
import { createCustomTextFieldMetadata } from 'test/integration/metadata/suites/field-metadata/utils/create-custom-text-field-metadata.util';
|
||||||
import { createOneFieldMetadataFactory } from 'test/integration/metadata/suites/field-metadata/utils/create-one-field-metadata-factory.util';
|
import { createOneFieldMetadataFactory } from 'test/integration/metadata/suites/field-metadata/utils/create-one-field-metadata-factory.util';
|
||||||
import { deleteOneFieldMetadataItemFactory } from 'test/integration/metadata/suites/field-metadata/utils/delete-one-field-metadata-factory.util';
|
import { deleteOneFieldMetadataItemFactory } from 'test/integration/metadata/suites/field-metadata/utils/delete-one-field-metadata-factory.util';
|
||||||
@ -12,29 +10,12 @@ import { updateOneObjectMetadataItemFactory } from 'test/integration/metadata/su
|
|||||||
import { makeMetadataAPIRequestWithMemberRole } from 'test/integration/metadata/suites/utils/make-metadata-api-request-with-member-role.util';
|
import { makeMetadataAPIRequestWithMemberRole } from 'test/integration/metadata/suites/utils/make-metadata-api-request-with-member-role.util';
|
||||||
import { FieldMetadataType } from 'twenty-shared/types';
|
import { FieldMetadataType } from 'twenty-shared/types';
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
describe('datamodel permissions', () => {
|
describe('datamodel permissions', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {});
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
describe('fieldMetadata', () => {
|
describe('fieldMetadata', () => {
|
||||||
let listingObjectId = '';
|
let listingObjectId = '';
|
||||||
let testFieldId = '';
|
let testFieldId = '';
|
||||||
|
|||||||
@ -32,14 +32,6 @@ describe('Security permissions', () => {
|
|||||||
const response = await makeGraphqlAPIRequest({ query });
|
const response = await makeGraphqlAPIRequest({ query });
|
||||||
|
|
||||||
originalWorkspaceState = response.body.data.currentWorkspace;
|
originalWorkspaceState = response.body.data.currentWorkspace;
|
||||||
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|||||||
@ -1,34 +1,11 @@
|
|||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
|
|
||||||
const client = request(`http://localhost:${APP_PORT}`);
|
const client = request(`http://localhost:${APP_PORT}`);
|
||||||
|
|
||||||
describe('workspace invitation permissions', () => {
|
describe('workspace invitation permissions', () => {
|
||||||
beforeAll(async () => {
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw a permission error when user does not have permission to send invitation', async () => {
|
it('should throw a permission error when user does not have permission to send invitation', async () => {
|
||||||
const queryData = {
|
const queryData = {
|
||||||
query: `
|
query: `
|
||||||
|
|||||||
@ -3,10 +3,8 @@ import { deleteOneOperationFactory } from 'test/integration/graphql/utils/delete
|
|||||||
import { makeGraphqlAPIRequestWithMemberRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-member-role.util';
|
import { makeGraphqlAPIRequestWithMemberRole } from 'test/integration/graphql/utils/make-graphql-api-request-with-member-role.util';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
||||||
import { restoreOneOperationFactory } from 'test/integration/graphql/utils/restore-one-operation-factory.util';
|
import { restoreOneOperationFactory } from 'test/integration/graphql/utils/restore-one-operation-factory.util';
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
|
import { updateOneOperationFactory } from 'test/integration/graphql/utils/update-one-operation-factory.util';
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { DEV_SEED_WORKSPACE_MEMBER_IDS } from 'src/database/typeorm-seeds/workspace/workspace-members';
|
import { DEV_SEED_WORKSPACE_MEMBER_IDS } from 'src/database/typeorm-seeds/workspace/workspace-members';
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
import { PermissionsExceptionMessage } from 'src/engine/metadata-modules/permissions/permissions.exception';
|
||||||
@ -19,25 +17,6 @@ const WORKSPACE_MEMBER_GQL_FIELDS = `
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
describe('workspace members permissions', () => {
|
describe('workspace members permissions', () => {
|
||||||
beforeAll(async () => {
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
describe('updateOne', () => {
|
describe('updateOne', () => {
|
||||||
it('should allow update when user is updating themself (member role)', async () => {
|
it('should allow update when user is updating themself (member role)', async () => {
|
||||||
const graphqlOperation = updateOneOperationFactory({
|
const graphqlOperation = updateOneOperationFactory({
|
||||||
|
|||||||
@ -33,14 +33,6 @@ describe('workspace permissions', () => {
|
|||||||
const response = await makeGraphqlAPIRequest({ query });
|
const response = await makeGraphqlAPIRequest({ query });
|
||||||
|
|
||||||
originalWorkspaceState = response.body.data.currentWorkspace;
|
originalWorkspaceState = response.body.data.currentWorkspace;
|
||||||
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
|
|||||||
@ -1,33 +1,10 @@
|
|||||||
import request from 'supertest';
|
import request from 'supertest';
|
||||||
import { makeGraphqlAPIRequest } from 'test/integration/graphql/utils/make-graphql-api-request.util';
|
|
||||||
import { updateFeatureFlagFactory } from 'test/integration/graphql/utils/update-feature-flag-factory.util';
|
|
||||||
|
|
||||||
import { SEED_APPLE_WORKSPACE_ID } from 'src/database/typeorm-seeds/core/workspaces';
|
|
||||||
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { ErrorCode } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
|
|
||||||
const client = request(`http://localhost:${APP_PORT}`);
|
const client = request(`http://localhost:${APP_PORT}`);
|
||||||
|
|
||||||
describe('deleteUser', () => {
|
describe('deleteUser', () => {
|
||||||
beforeAll(async () => {
|
|
||||||
const enablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(enablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
const disablePermissionsQuery = updateFeatureFlagFactory(
|
|
||||||
SEED_APPLE_WORKSPACE_ID,
|
|
||||||
'IsPermissionsEnabled',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
await makeGraphqlAPIRequest(disablePermissionsQuery);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not allow to delete user if they are the unique admin of a workspace', async () => {
|
it('should not allow to delete user if they are the unique admin of a workspace', async () => {
|
||||||
const query = {
|
const query = {
|
||||||
query: `
|
query: `
|
||||||
|
|||||||
Reference in New Issue
Block a user