refactor(auth): add workspaces selection (#12098)
This commit is contained in:
@ -37,6 +37,7 @@ import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role
|
||||
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
|
||||
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
|
||||
|
||||
export type GraphqlQueryResolverExecutionArgs<Input extends ResolverArgs> = {
|
||||
args: Input;
|
||||
@ -83,11 +84,15 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
try {
|
||||
const { authContext, objectMetadataItemWithFieldMaps } = options;
|
||||
|
||||
const workspace = authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
await this.validate(args, options);
|
||||
|
||||
const workspaceDataSource =
|
||||
await this.twentyORMGlobalManager.getDataSourceForWorkspace({
|
||||
workspaceId: authContext.workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
shouldFailIfMetadataNotFound: false,
|
||||
});
|
||||
|
||||
@ -124,7 +129,7 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
|
||||
const roleId = await this.userRoleService.getRoleIdForUserWorkspace({
|
||||
userWorkspaceId: authContext.userWorkspaceId,
|
||||
workspaceId: authContext.workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
|
||||
const executedByApiKey = isDefined(authContext.apiKey);
|
||||
@ -169,7 +174,7 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
const resultWithGetters = await this.queryResultGettersFactory.create(
|
||||
results,
|
||||
objectMetadataItemWithFieldMaps,
|
||||
authContext.workspace.id,
|
||||
workspace.id,
|
||||
options.objectMetadataMaps,
|
||||
);
|
||||
|
||||
@ -191,6 +196,10 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
) {
|
||||
const { authContext, objectMetadataItemWithFieldMaps } = options;
|
||||
|
||||
const workspace = authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
if (
|
||||
Object.keys(OBJECTS_WITH_SETTINGS_PERMISSIONS_REQUIREMENTS).includes(
|
||||
objectMetadataItemWithFieldMaps.nameSingular,
|
||||
@ -206,7 +215,7 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
await this.permissionsService.userHasWorkspaceSettingPermission({
|
||||
userWorkspaceId: authContext.userWorkspaceId,
|
||||
setting: permissionRequired,
|
||||
workspaceId: authContext.workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
isExecutedByApiKey: isDefined(authContext.apiKey),
|
||||
});
|
||||
|
||||
@ -231,11 +240,15 @@ export abstract class GraphqlQueryBaseResolverService<
|
||||
const requiredPermission =
|
||||
this.getRequiredPermissionForMethod(operationName);
|
||||
|
||||
const workspace = options.authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
const userHasPermission =
|
||||
await this.permissionsService.userHasObjectRecordsPermission({
|
||||
userWorkspaceId: options.authContext.userWorkspaceId,
|
||||
requiredPermission,
|
||||
workspaceId: options.authContext.workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
isExecutedByApiKey: isDefined(options.authContext.apiKey),
|
||||
objectMetadataId,
|
||||
});
|
||||
|
||||
@ -7,6 +7,7 @@ import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner
|
||||
import { AuthContext } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { objectRecordChangedValues } from 'src/engine/core-modules/event-emitter/utils/object-record-changed-values';
|
||||
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
|
||||
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
|
||||
|
||||
@Injectable()
|
||||
export class ApiEventEmitterService {
|
||||
@ -33,7 +34,7 @@ export class ApiEventEmitterService {
|
||||
after: record,
|
||||
},
|
||||
})),
|
||||
workspaceId: authContext.workspace.id,
|
||||
workspaceId: authContext.workspace?.id,
|
||||
});
|
||||
}
|
||||
|
||||
@ -50,6 +51,10 @@ export class ApiEventEmitterService {
|
||||
authContext: AuthContext;
|
||||
objectMetadataItem: ObjectMetadataInterface;
|
||||
}): void {
|
||||
const workspace = authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
const mappedExistingRecords = existingRecords.reduce(
|
||||
(acc, { id, ...record }) => ({
|
||||
...acc,
|
||||
@ -84,7 +89,7 @@ export class ApiEventEmitterService {
|
||||
},
|
||||
};
|
||||
}),
|
||||
workspaceId: authContext.workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
}
|
||||
|
||||
@ -97,6 +102,10 @@ export class ApiEventEmitterService {
|
||||
authContext: AuthContext;
|
||||
objectMetadataItem: ObjectMetadataInterface;
|
||||
}): void {
|
||||
const workspace = authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
this.workspaceEventEmitter.emitDatabaseBatchEvent({
|
||||
objectMetadataNameSingular: objectMetadataItem.nameSingular,
|
||||
action: DatabaseEventAction.DELETED,
|
||||
@ -111,7 +120,7 @@ export class ApiEventEmitterService {
|
||||
},
|
||||
};
|
||||
}),
|
||||
workspaceId: authContext.workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
}
|
||||
|
||||
@ -124,6 +133,10 @@ export class ApiEventEmitterService {
|
||||
authContext: AuthContext;
|
||||
objectMetadataItem: ObjectMetadataInterface;
|
||||
}): void {
|
||||
const workspace = authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
this.workspaceEventEmitter.emitDatabaseBatchEvent({
|
||||
objectMetadataNameSingular: objectMetadataItem.nameSingular,
|
||||
action: DatabaseEventAction.RESTORED,
|
||||
@ -138,7 +151,7 @@ export class ApiEventEmitterService {
|
||||
},
|
||||
};
|
||||
}),
|
||||
workspaceId: authContext.workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
}
|
||||
|
||||
@ -151,6 +164,10 @@ export class ApiEventEmitterService {
|
||||
authContext: AuthContext;
|
||||
objectMetadataItem: ObjectMetadataInterface;
|
||||
}): void {
|
||||
const workspace = authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
this.workspaceEventEmitter.emitDatabaseBatchEvent({
|
||||
objectMetadataNameSingular: objectMetadataItem.nameSingular,
|
||||
action: DatabaseEventAction.DESTROYED,
|
||||
@ -165,7 +182,7 @@ export class ApiEventEmitterService {
|
||||
},
|
||||
};
|
||||
}),
|
||||
workspaceId: authContext.workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import { FieldMetadataInterface } from 'src/engine/metadata-modules/field-metada
|
||||
import { RecordPositionService } from 'src/engine/core-modules/record-position/services/record-position.service';
|
||||
import { FieldMetadataMap } from 'src/engine/metadata-modules/types/field-metadata-map';
|
||||
import { RecordInputTransformerService } from 'src/engine/core-modules/record-transformer/services/record-input-transformer.service';
|
||||
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
|
||||
|
||||
type ArgPositionBackfillInput = {
|
||||
argIndex?: number;
|
||||
@ -171,7 +172,10 @@ export class QueryRunnerArgsFactory {
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
const workspaceId = options.authContext.workspace.id;
|
||||
const workspace = options.authContext.workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
let isFieldPositionPresent = false;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@ -192,7 +196,7 @@ export class QueryRunnerArgsFactory {
|
||||
const newValue = await this.recordPositionService.buildRecordPosition(
|
||||
{
|
||||
value,
|
||||
workspaceId,
|
||||
workspaceId: workspace.id,
|
||||
objectMetadata: {
|
||||
isCustom: options.objectMetadataItemWithFieldMaps.isCustom,
|
||||
nameSingular:
|
||||
@ -234,7 +238,7 @@ export class QueryRunnerArgsFactory {
|
||||
'position',
|
||||
await this.recordPositionService.buildRecordPosition({
|
||||
value: 'first',
|
||||
workspaceId,
|
||||
workspaceId: workspace.id,
|
||||
objectMetadata: {
|
||||
isCustom: options.objectMetadataItemWithFieldMaps.isCustom,
|
||||
nameSingular:
|
||||
|
||||
@ -22,6 +22,7 @@ import { WorkspaceQueryHookKey } from 'src/engine/api/graphql/workspace-query-ru
|
||||
import { WorkspaceQueryHookStorage } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/storage/workspace-query-hook.storage';
|
||||
import { WorkspaceQueryHookType } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/types/workspace-query-hook.type';
|
||||
import { WorkspaceQueryHookMetadataAccessor } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook-metadata.accessor';
|
||||
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceQueryHookExplorer implements OnModuleInit {
|
||||
@ -89,6 +90,10 @@ export class WorkspaceQueryHookExplorer implements OnModuleInit {
|
||||
): Promise<ReturnType<WorkspacePreQueryHookInstance['execute']>> {
|
||||
const methodName = 'execute';
|
||||
|
||||
const workspace = executeParams?.[0].workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
if (isRequestScoped) {
|
||||
const contextId = createContextId();
|
||||
|
||||
@ -96,7 +101,7 @@ export class WorkspaceQueryHookExplorer implements OnModuleInit {
|
||||
this.moduleRef.registerRequestByContextId(
|
||||
{
|
||||
req: {
|
||||
workspaceId: executeParams?.[0].workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
},
|
||||
},
|
||||
contextId,
|
||||
@ -152,6 +157,10 @@ export class WorkspaceQueryHookExplorer implements OnModuleInit {
|
||||
): Promise<ReturnType<WorkspacePostQueryHookInstance['execute']>> {
|
||||
const methodName = 'execute';
|
||||
|
||||
const workspace = executeParams?.[0].workspace;
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
const transformedPayload = this.transformPayload(executeParams[2]);
|
||||
|
||||
if (isRequestScoped) {
|
||||
@ -161,7 +170,7 @@ export class WorkspaceQueryHookExplorer implements OnModuleInit {
|
||||
this.moduleRef.registerRequestByContextId(
|
||||
{
|
||||
req: {
|
||||
workspaceId: executeParams?.[0].workspace.id,
|
||||
workspaceId: workspace.id,
|
||||
userWorkspaceId: executeParams?.[0].userWorkspaceId,
|
||||
apiKey: executeParams?.[0].apiKey,
|
||||
workspaceMemberId: executeParams?.[0].workspaceMemberId,
|
||||
|
||||
@ -18,6 +18,7 @@ import { getObjectMetadataMapItemByNamePlural } from 'src/engine/metadata-module
|
||||
import { getObjectMetadataMapItemByNameSingular } from 'src/engine/metadata-modules/utils/get-object-metadata-map-item-by-name-singular.util';
|
||||
import { WorkspaceMetadataCacheService } from 'src/engine/metadata-modules/workspace-metadata-cache/services/workspace-metadata-cache.service';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
import { workspaceValidator } from 'src/engine/core-modules/workspace/workspace.validate';
|
||||
|
||||
@Injectable()
|
||||
export class CoreQueryBuilderFactory {
|
||||
@ -42,6 +43,8 @@ export class CoreQueryBuilderFactory {
|
||||
const { workspace } =
|
||||
await this.accessTokenService.validateTokenByRequest(request);
|
||||
|
||||
workspaceValidator.assertIsDefinedOrThrow(workspace);
|
||||
|
||||
const currentCacheVersion =
|
||||
await this.workspaceCacheStorageService.getMetadataVersion(workspace.id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user