4257f30f12
In this PR we are handling permissions when using twentyORMGlobalManager, and handling permissions for rest api and api key
106 lines
3.8 KiB
TypeScript
106 lines
3.8 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
|
|
import {
|
|
GraphqlQueryBaseResolverService,
|
|
GraphqlQueryResolverExecutionArgs,
|
|
} from 'src/engine/api/graphql/graphql-query-runner/interfaces/base-resolver-service';
|
|
import { ObjectRecord } from 'src/engine/api/graphql/workspace-query-builder/interfaces/object-record.interface';
|
|
import { WorkspaceQueryRunnerOptions } from 'src/engine/api/graphql/workspace-query-runner/interfaces/query-runner-option.interface';
|
|
import { DestroyOneResolverArgs } from 'src/engine/api/graphql/workspace-resolver-builder/interfaces/workspace-resolvers-builder.interface';
|
|
|
|
import { QUERY_MAX_RECORDS } from 'src/engine/api/graphql/graphql-query-runner/constants/query-max-records.constant';
|
|
import {
|
|
GraphqlQueryRunnerException,
|
|
GraphqlQueryRunnerExceptionCode,
|
|
} from 'src/engine/api/graphql/graphql-query-runner/errors/graphql-query-runner.exception';
|
|
import { ObjectRecordsToGraphqlConnectionHelper } from 'src/engine/api/graphql/graphql-query-runner/helpers/object-records-to-graphql-connection.helper';
|
|
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
import { formatResult } from 'src/engine/twenty-orm/utils/format-result.util';
|
|
|
|
@Injectable()
|
|
export class GraphqlQueryDestroyOneResolverService extends GraphqlQueryBaseResolverService<
|
|
DestroyOneResolverArgs,
|
|
ObjectRecord
|
|
> {
|
|
async resolve(
|
|
executionArgs: GraphqlQueryResolverExecutionArgs<DestroyOneResolverArgs>,
|
|
featureFlagsMap: Record<FeatureFlagKey, boolean>,
|
|
): Promise<ObjectRecord> {
|
|
const { authContext, objectMetadataItemWithFieldMaps, objectMetadataMaps } =
|
|
executionArgs.options;
|
|
|
|
const { roleId } = executionArgs;
|
|
|
|
const queryBuilder = executionArgs.repository.createQueryBuilder(
|
|
objectMetadataItemWithFieldMaps.nameSingular,
|
|
);
|
|
|
|
const nonFormattedDeletedObjectRecords = await queryBuilder
|
|
.delete()
|
|
.where({ id: executionArgs.args.id })
|
|
.returning('*')
|
|
.execute();
|
|
|
|
if (!nonFormattedDeletedObjectRecords.affected) {
|
|
throw new GraphqlQueryRunnerException(
|
|
'Record not found',
|
|
GraphqlQueryRunnerExceptionCode.RECORD_NOT_FOUND,
|
|
);
|
|
}
|
|
|
|
const deletedRecords = formatResult<ObjectRecord[]>(
|
|
nonFormattedDeletedObjectRecords.raw,
|
|
objectMetadataItemWithFieldMaps,
|
|
objectMetadataMaps,
|
|
featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled],
|
|
);
|
|
|
|
this.apiEventEmitterService.emitDestroyEvents(
|
|
deletedRecords,
|
|
authContext,
|
|
objectMetadataItemWithFieldMaps,
|
|
);
|
|
|
|
if (executionArgs.graphqlQuerySelectedFieldsResult.relations) {
|
|
await this.processNestedRelationsHelper.processNestedRelations({
|
|
objectMetadataMaps,
|
|
parentObjectMetadataItem: objectMetadataItemWithFieldMaps,
|
|
parentObjectRecords: deletedRecords,
|
|
relations: executionArgs.graphqlQuerySelectedFieldsResult.relations,
|
|
limit: QUERY_MAX_RECORDS,
|
|
authContext,
|
|
dataSource: executionArgs.dataSource,
|
|
isNewRelationEnabled:
|
|
featureFlagsMap[FeatureFlagKey.IsNewRelationEnabled],
|
|
roleId,
|
|
shouldBypassPermissionChecks: executionArgs.isExecutedByApiKey,
|
|
});
|
|
}
|
|
|
|
const typeORMObjectRecordsParser =
|
|
new ObjectRecordsToGraphqlConnectionHelper(
|
|
objectMetadataMaps,
|
|
featureFlagsMap,
|
|
);
|
|
|
|
return typeORMObjectRecordsParser.processRecord({
|
|
objectRecord: deletedRecords[0],
|
|
objectName: objectMetadataItemWithFieldMaps.nameSingular,
|
|
take: 1,
|
|
totalCount: 1,
|
|
});
|
|
}
|
|
|
|
async validate(
|
|
args: DestroyOneResolverArgs,
|
|
_options: WorkspaceQueryRunnerOptions,
|
|
): Promise<void> {
|
|
if (!args.id) {
|
|
throw new GraphqlQueryRunnerException(
|
|
'Missing id',
|
|
GraphqlQueryRunnerExceptionCode.INVALID_QUERY_INPUT,
|
|
);
|
|
}
|
|
}
|
|
}
|