@lightdash/common 0.1342.1 → 0.1344.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -205,6 +205,10 @@ exports.organizationMemberAbilities = {
205
205
  organizationUuid: member.organizationUuid,
206
206
  type: projects_1.ProjectType.PREVIEW,
207
207
  });
208
+ can('delete', 'Project', {
209
+ organizationUuid: member.organizationUuid,
210
+ type: projects_1.ProjectType.PREVIEW,
211
+ });
208
212
  },
209
213
  admin(member, { can }) {
210
214
  exports.organizationMemberAbilities.developer(member, { can });
@@ -221,6 +225,9 @@ exports.organizationMemberAbilities = {
221
225
  organizationUuid: member.organizationUuid,
222
226
  type: { $in: [projects_1.ProjectType.DEFAULT, projects_1.ProjectType.PREVIEW] },
223
227
  });
228
+ can('delete', 'Project', {
229
+ organizationUuid: member.organizationUuid,
230
+ });
224
231
  can('manage', 'Project', {
225
232
  organizationUuid: member.organizationUuid,
226
233
  });
@@ -911,33 +911,45 @@ describe('Organization member permissions', () => {
911
911
  membership: organizationMemberAbility_mock_1.ORGANIZATION_ADMIN,
912
912
  canCreateProject: true,
913
913
  canCreatePreview: true,
914
+ canDeleteProject: true,
915
+ canDeletePreview: true,
914
916
  },
915
917
  {
916
918
  membership: organizationMemberAbility_mock_1.ORGANIZATION_DEVELOPER,
917
919
  canCreateProject: false,
918
920
  canCreatePreview: true,
921
+ canDeleteProject: false,
922
+ canDeletePreview: true,
919
923
  },
920
924
  {
921
925
  membership: organizationMemberAbility_mock_1.ORGANIZATION_MEMBER,
922
926
  canCreateProject: false,
923
927
  canCreatePreview: false,
928
+ canDeleteProject: false,
929
+ canDeletePreview: false,
924
930
  },
925
931
  {
926
932
  membership: organizationMemberAbility_mock_1.ORGANIZATION_VIEWER,
927
933
  canCreateProject: false,
928
934
  canCreatePreview: false,
935
+ canDeleteProject: false,
936
+ canDeletePreview: false,
929
937
  },
930
938
  {
931
939
  membership: organizationMemberAbility_mock_1.ORGANIZATION_INTERACTIVE_VIEWER,
932
940
  canCreateProject: false,
933
941
  canCreatePreview: false,
942
+ canDeleteProject: false,
943
+ canDeletePreview: false,
934
944
  },
935
945
  {
936
946
  membership: organizationMemberAbility_mock_1.ORGANIZATION_EDITOR,
937
947
  canCreateProject: false,
938
948
  canCreatePreview: false,
949
+ canDeleteProject: false,
950
+ canDeletePreview: false,
939
951
  },
940
- ].forEach(({ membership, canCreateProject, canCreatePreview }) => {
952
+ ].forEach(({ membership, canCreateProject, canCreatePreview, canDeleteProject, canDeletePreview, }) => {
941
953
  const ability = defineAbilityForOrganizationMember(membership);
942
954
  describe(`user is '${membership.role}' role`, () => {
943
955
  it('checks if users can create project in organization they belong to', () => {
@@ -964,6 +976,28 @@ describe('Organization member permissions', () => {
964
976
  type: projects_1.ProjectType.PREVIEW,
965
977
  }))).toEqual(false);
966
978
  });
979
+ it('checks if users can delete a project in organization they belong to', () => {
980
+ expect(ability.can('delete', (0, ability_1.subject)('Project', {
981
+ organizationUuid: membership.organizationUuid,
982
+ }))).toEqual(canDeleteProject);
983
+ });
984
+ it('checks that users cannot delete a project in another organization', () => {
985
+ expect(ability.can('delete', (0, ability_1.subject)('Project', {
986
+ organizationUuid: '789',
987
+ }))).toEqual(false);
988
+ });
989
+ it('checks if users can delete a PREVIEW project in organization they belong to', () => {
990
+ expect(ability.can('delete', (0, ability_1.subject)('Project', {
991
+ organizationUuid: membership.organizationUuid,
992
+ type: projects_1.ProjectType.PREVIEW,
993
+ }))).toEqual(canDeletePreview);
994
+ });
995
+ it('checks that users cannot delete a PREVIEW project in another organization', () => {
996
+ expect(ability.can('delete', (0, ability_1.subject)('Project', {
997
+ organizationUuid: '789',
998
+ type: projects_1.ProjectType.PREVIEW,
999
+ }))).toEqual(false);
1000
+ });
967
1001
  });
968
1002
  });
969
1003
  });
@@ -187,6 +187,10 @@ exports.projectMemberAbilities = {
187
187
  can('manage', 'CompileProject', {
188
188
  projectUuid: member.projectUuid,
189
189
  });
190
+ can('delete', 'Project', {
191
+ type: projects_1.ProjectType.PREVIEW,
192
+ createdByUserUuid: member.userUuid,
193
+ });
190
194
  can('create', 'Project', {
191
195
  upstreamProjectUuid: member.projectUuid,
192
196
  type: projects_1.ProjectType.PREVIEW,
@@ -194,6 +198,9 @@ exports.projectMemberAbilities = {
194
198
  },
195
199
  admin(member, { can }) {
196
200
  exports.projectMemberAbilities.developer(member, { can });
201
+ can('delete', 'Project', {
202
+ projectUuid: member.projectUuid,
203
+ });
197
204
  can('manage', 'Project', {
198
205
  projectUuid: member.projectUuid,
199
206
  });
@@ -737,24 +737,29 @@ describe('Project member permissions', () => {
737
737
  {
738
738
  membership: projectMemberAbility_mock_1.PROJECT_ADMIN,
739
739
  canCreatePreview: true,
740
+ canDeleteTheirOwnPreview: true,
740
741
  },
741
742
  {
742
743
  membership: projectMemberAbility_mock_1.PROJECT_DEVELOPER,
743
744
  canCreatePreview: true,
745
+ canDeleteTheirOwnPreview: true,
744
746
  },
745
747
  {
746
748
  membership: projectMemberAbility_mock_1.PROJECT_EDITOR,
747
749
  canCreatePreview: false,
750
+ canDeleteTheirOwnPreview: false,
748
751
  },
749
752
  {
750
753
  membership: projectMemberAbility_mock_1.PROJECT_INTERACTIVE_VIEWER,
751
754
  canCreatePreview: false,
755
+ canDeleteTheirOwnPreview: false,
752
756
  },
753
757
  {
754
758
  membership: projectMemberAbility_mock_1.PROJECT_VIEWER,
755
759
  canCreatePreview: false,
760
+ canDeleteTheirOwnPreview: false,
756
761
  },
757
- ].forEach(({ membership, canCreatePreview }) => {
762
+ ].forEach(({ membership, canCreatePreview, canDeleteTheirOwnPreview }) => {
758
763
  describe('test project preview permissions', () => {
759
764
  const ability = defineAbilityForProjectMember(membership);
760
765
  it('checks if user can create PREVIEW projects', () => {
@@ -769,6 +774,18 @@ describe('Project member permissions', () => {
769
774
  type: projects_1.ProjectType.DEFAULT,
770
775
  }))).toEqual(false);
771
776
  });
777
+ it('checks if user can delete their own PREVIEW projects', () => {
778
+ expect(ability.can('delete', (0, ability_1.subject)('Project', {
779
+ createdByUserUuid: membership.userUuid,
780
+ type: projects_1.ProjectType.PREVIEW,
781
+ }))).toEqual(canDeleteTheirOwnPreview);
782
+ });
783
+ it('checks that users cannot delete other users PREVIEW projects', () => {
784
+ expect(ability.can('delete', (0, ability_1.subject)('Project', {
785
+ createdByUserUuid: '1234',
786
+ type: projects_1.ProjectType.PREVIEW,
787
+ }))).toEqual(false);
788
+ });
772
789
  });
773
790
  });
774
791
  });
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ import { type ApiCalculateTotalResponse, type ChartHistory, type ChartVersion, t
11
11
  import { type SearchResults } from './types/search';
12
12
  import { type ShareUrl } from './types/share';
13
13
  import { type SlackSettings } from './types/slackSettings';
14
+ import { type ApiCreateTagResponse } from './types/tags';
14
15
  import { type ApiCreateComment, type ApiDeleteComment, type ApiGetComments } from './types/api/comments';
15
16
  import { type Email } from './types/api/email';
16
17
  import { type ApiSuccessEmpty } from './types/api/success';
@@ -374,7 +375,7 @@ export type ApiAiGetDashboardSummaryResponse = {
374
375
  status: 'ok';
375
376
  results: DashboardSummary;
376
377
  };
377
- type ApiResults = ApiQueryResults | ApiSqlQueryResults | ApiCompiledQueryResults | ApiExploresResults | ApiExploreResults | ApiStatusResults | ApiRefreshResults | ApiHealthResults | Organization | LightdashUser | LoginOptions | SavedChart | SavedChart[] | Space[] | InviteLink | OrganizationProject[] | Project | WarehouseCredentials | OrganizationMemberProfile[] | ProjectCatalog | TablesConfiguration | Dashboard | DashboardBasicDetails[] | OnboardingStatus | Dashboard[] | DeleteOpenIdentity | ApiFlashResults | Record<OpenIdIdentitySummary['issuerType'], OpenIdIdentitySummary[]> | FilterableField[] | DashboardAvailableFilters | ProjectSavedChartStatus | null | Array<unknown> | ApiJobStartedResults | ApiCreateUserTokenResults | CreatePersonalAccessToken | PersonalAccessToken | ProjectMemberProfile[] | ProjectGroupAccess | SearchResults | Space | ShareUrl | SlackSettings | ApiSlackChannelsResponse['results'] | UserActivity | SchedulerAndTargets | SchedulerAndTargets[] | FieldValueSearchResult | ApiDownloadCsv | AllowedEmailDomains | UpdateAllowedEmailDomains | UserAllowedOrganization[] | EmailStatusExpiring | ApiScheduledDownloadCsv | PinnedItems | ViewStatistics | SchedulerWithLogs | ValidationResponse[] | ChartHistory | ChartVersion | Array<GitRepo> | PullRequestCreated | GitIntegrationConfiguration | UserWarehouseCredentials | ApiJobStatusResponse['results'] | ApiJobScheduledResponse['results'] | ApiSshKeyPairResponse['results'] | MostPopularAndRecentlyUpdated | ApiCalculateTotalResponse['results'] | Record<string, DbtExposure> | ApiCreateComment['results'] | ApiGetComments['results'] | ApiDeleteComment | ApiSuccessEmpty | ApiCreateProjectResults | ApiAiDashboardSummaryResponse['results'] | ApiAiGetDashboardSummaryResponse['results'] | ApiCatalogMetadataResults | ApiCatalogAnalyticsResults | ApiPromotionChangesResponse['results'] | ApiWarehouseTableFields['results'] | ApiTogglePinnedItem['results'] | ApiOrganizationMemberProfiles['results'] | ApiSqlChart['results'] | ApiCreateSqlChart['results'] | ApiUpdateSqlChart['results'] | ApiContentResponse['results'] | ApiChartContentResponse['results'] | ApiSqlRunnerJobStatusResponse['results'] | ApiSemanticLayerClientInfo['results'] | ApiSemanticViewerChartCreate['results'] | ApiSemanticViewerChartGet['results'] | ApiSemanticViewerChartUpdate['results'] | ApiCreateVirtualView['results'] | ApiGithubDbtWritePreview['results'] | ApiMetricsCatalog['results'] | ApiGroupListResponse['results'];
378
+ type ApiResults = ApiQueryResults | ApiSqlQueryResults | ApiCompiledQueryResults | ApiExploresResults | ApiExploreResults | ApiStatusResults | ApiRefreshResults | ApiHealthResults | Organization | LightdashUser | LoginOptions | SavedChart | SavedChart[] | Space[] | InviteLink | OrganizationProject[] | Project | WarehouseCredentials | OrganizationMemberProfile[] | ProjectCatalog | TablesConfiguration | Dashboard | DashboardBasicDetails[] | OnboardingStatus | Dashboard[] | DeleteOpenIdentity | ApiFlashResults | Record<OpenIdIdentitySummary['issuerType'], OpenIdIdentitySummary[]> | FilterableField[] | DashboardAvailableFilters | ProjectSavedChartStatus | null | Array<unknown> | ApiJobStartedResults | ApiCreateUserTokenResults | CreatePersonalAccessToken | PersonalAccessToken | ProjectMemberProfile[] | ProjectGroupAccess | SearchResults | Space | ShareUrl | SlackSettings | ApiSlackChannelsResponse['results'] | UserActivity | SchedulerAndTargets | SchedulerAndTargets[] | FieldValueSearchResult | ApiDownloadCsv | AllowedEmailDomains | UpdateAllowedEmailDomains | UserAllowedOrganization[] | EmailStatusExpiring | ApiScheduledDownloadCsv | PinnedItems | ViewStatistics | SchedulerWithLogs | ValidationResponse[] | ChartHistory | ChartVersion | Array<GitRepo> | PullRequestCreated | GitIntegrationConfiguration | UserWarehouseCredentials | ApiJobStatusResponse['results'] | ApiJobScheduledResponse['results'] | ApiSshKeyPairResponse['results'] | MostPopularAndRecentlyUpdated | ApiCalculateTotalResponse['results'] | Record<string, DbtExposure> | ApiCreateComment['results'] | ApiGetComments['results'] | ApiDeleteComment | ApiSuccessEmpty | ApiCreateProjectResults | ApiAiDashboardSummaryResponse['results'] | ApiAiGetDashboardSummaryResponse['results'] | ApiCatalogMetadataResults | ApiCatalogAnalyticsResults | ApiPromotionChangesResponse['results'] | ApiWarehouseTableFields['results'] | ApiTogglePinnedItem['results'] | ApiOrganizationMemberProfiles['results'] | ApiSqlChart['results'] | ApiCreateSqlChart['results'] | ApiUpdateSqlChart['results'] | ApiContentResponse['results'] | ApiChartContentResponse['results'] | ApiSqlRunnerJobStatusResponse['results'] | ApiSemanticLayerClientInfo['results'] | ApiSemanticViewerChartCreate['results'] | ApiSemanticViewerChartGet['results'] | ApiSemanticViewerChartUpdate['results'] | ApiCreateVirtualView['results'] | ApiGithubDbtWritePreview['results'] | ApiMetricsCatalog['results'] | ApiGroupListResponse['results'] | ApiCreateTagResponse['results'];
378
379
  export type ApiResponse<T extends ApiResults = ApiResults> = {
379
380
  status: 'ok';
380
381
  results: T;
@@ -502,10 +503,10 @@ export declare enum DBFieldTypes {
502
503
  }
503
504
  export declare const sensitiveDbtCredentialsFieldNames: readonly ["personal_access_token", "api_key"];
504
505
  export declare const DbtProjectTypeLabels: Record<DbtProjectType, string>;
505
- export type CreateProject = Omit<Project, 'projectUuid' | 'organizationUuid' | 'schedulerTimezone'> & {
506
+ export type CreateProject = Omit<Project, 'projectUuid' | 'organizationUuid' | 'schedulerTimezone' | 'createdByUserUuid'> & {
506
507
  warehouseConnection: CreateWarehouseCredentials;
507
508
  };
508
- export type UpdateProject = Omit<Project, 'projectUuid' | 'organizationUuid' | 'type' | 'schedulerTimezone'> & {
509
+ export type UpdateProject = Omit<Project, 'projectUuid' | 'organizationUuid' | 'type' | 'schedulerTimezone' | 'createdByUserUuid'> & {
509
510
  warehouseConnection: CreateWarehouseCredentials;
510
511
  };
511
512
  export declare const getResultValueArray: (rows: ResultRow[], preferRaw?: boolean, calculateMinAndMax?: boolean) => {
@@ -44,6 +44,7 @@ export type OrganizationProject = {
44
44
  projectUuid: string;
45
45
  name: string;
46
46
  type: ProjectType;
47
+ createdByUserUuid: string | null;
47
48
  warehouseType: WarehouseTypes;
48
49
  requireUserCredentials: boolean;
49
50
  };
@@ -231,6 +231,7 @@ export type Project = {
231
231
  dbtVersion: SupportedDbtVersions;
232
232
  semanticLayerConnection?: SemanticLayerConnection;
233
233
  schedulerTimezone: string;
234
+ createdByUserUuid: string | null;
234
235
  };
235
236
  export type ProjectSummary = Pick<Project, 'name' | 'projectUuid' | 'organizationUuid' | 'type' | 'upstreamProjectUuid'>;
236
237
  export type ApiProjectResponse = {
@@ -11,3 +11,9 @@ export type ApiGetTagsResponse = {
11
11
  status: 'ok';
12
12
  results: Tag[];
13
13
  };
14
+ export type ApiCreateTagResponse = {
15
+ status: 'ok';
16
+ results: {
17
+ tagUuid: string;
18
+ };
19
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/common",
3
- "version": "0.1342.1",
3
+ "version": "0.1344.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [