diff --git a/packages/twenty-server/src/engine/core-modules/api-key/api-key.resolver.ts b/packages/twenty-server/src/engine/core-modules/api-key/api-key.resolver.ts index 7723e96015..e1a084d4a3 100644 --- a/packages/twenty-server/src/engine/core-modules/api-key/api-key.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/api-key/api-key.resolver.ts @@ -5,6 +5,7 @@ import { type QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialE import { PermissionFlagType } from 'twenty-shared/constants'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; +import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity'; import { CreateApiKeyInput } from 'src/engine/core-modules/api-key/dtos/create-api-key.input'; import { GetApiKeyInput } from 'src/engine/core-modules/api-key/dtos/get-api-key.input'; @@ -17,7 +18,6 @@ import { import { apiKeyGraphqlApiExceptionHandler } from 'src/engine/core-modules/api-key/utils/api-key-graphql-api-exception-handler.util'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto'; @@ -126,20 +126,9 @@ export class ApiKeyResolver { @Parent() apiKey: ApiKeyEntity, @AuthWorkspace() workspace: WorkspaceEntity, ): Promise { - const rolesMap = await this.apiKeyRoleService.getRolesByApiKeys({ - apiKeyIds: [apiKey.id], + return this.apiKeyRoleService.getRoleDtoByApiKeyId({ + apiKeyId: apiKey.id, workspaceId: workspace.id, }); - - const role = rolesMap.get(apiKey.id); - - if (!role) { - throw new ApiKeyException( - `API key ${apiKey.id} has no role assigned`, - ApiKeyExceptionCode.API_KEY_NO_ROLE_ASSIGNED, - ); - } - - return role; } } diff --git a/packages/twenty-server/src/engine/core-modules/api-key/services/api-key-role.service.ts b/packages/twenty-server/src/engine/core-modules/api-key/services/api-key-role.service.ts index 5d9a9a8d82..9eafcef398 100644 --- a/packages/twenty-server/src/engine/core-modules/api-key/services/api-key-role.service.ts +++ b/packages/twenty-server/src/engine/core-modules/api-key/services/api-key-role.service.ts @@ -9,10 +9,12 @@ import { ApiKeyException, ApiKeyExceptionCode, } from 'src/engine/core-modules/api-key/exceptions/api-key.exception'; +import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util'; import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity'; import { RoleTargetService } from 'src/engine/metadata-modules/role-target/services/role-target.service'; import { type RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto'; import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; +import { fromFlatRoleToRoleDto } from 'src/engine/metadata-modules/role/utils/fromFlatRoleToRoleDto.util'; import { fromRoleEntityToRoleDto } from 'src/engine/metadata-modules/role/utils/fromRoleEntityToRoleDto.util'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; @@ -80,6 +82,43 @@ export class ApiKeyRoleService { return roleId; } + async getRoleDtoByApiKeyId({ + apiKeyId, + workspaceId, + }: { + apiKeyId: string; + workspaceId: string; + }): Promise { + const { apiKeyRoleMap, flatRoleMaps } = + await this.workspaceCacheService.getOrRecompute(workspaceId, [ + 'apiKeyRoleMap', + 'flatRoleMaps', + ]); + + const roleId = apiKeyRoleMap[apiKeyId]; + + if (!isDefined(roleId)) { + throw new ApiKeyException( + `API key ${apiKeyId} has no role assigned`, + ApiKeyExceptionCode.API_KEY_NO_ROLE_ASSIGNED, + ); + } + + const flatRole = findFlatEntityByIdInFlatEntityMaps({ + flatEntityId: roleId, + flatEntityMaps: flatRoleMaps, + }); + + if (!isDefined(flatRole)) { + throw new ApiKeyException( + `Role ${roleId} not found for API key ${apiKeyId}`, + ApiKeyExceptionCode.API_KEY_NO_ROLE_ASSIGNED, + ); + } + + return fromFlatRoleToRoleDto(flatRole); + } + private async validateAssignRoleInput({ apiKeyId, workspaceId,