refactor(auth): add workspaces selection (#12098)

This commit is contained in:
Antoine Moreaux
2025-06-13 16:17:35 +02:00
committed by GitHub
parent 836e2f792c
commit b1af98f93d
162 changed files with 3542 additions and 1340 deletions
@@ -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,
});
}
}