diff --git a/packages/cli/src/credentials/credentials.service.ts b/packages/cli/src/credentials/credentials.service.ts index 0ecfd31877bf2..01517c960adad 100644 --- a/packages/cli/src/credentials/credentials.service.ts +++ b/packages/cli/src/credentials/credentials.service.ts @@ -90,6 +90,19 @@ export class CredentialsService { let credentials = await this.credentialsRepository.findMany(options.listQueryOptions); if (isDefaultSelect) { + // Since we're filtering using project ID as part of the relation, + // we end up filtering out all the other relations, meaning that if + // it's shared to a project, it won't be able to find the home project. + // To solve this, we have to get all the relation now, even though + // we're deleting them later. + if ((options.listQueryOptions?.filter?.shared as { projectId?: string })?.projectId) { + const relations = await this.sharedCredentialsRepository.getAllRelationsForCredentials( + credentials.map((c) => c.id), + ); + credentials.forEach((c) => { + c.shared = relations.filter((r) => r.credentialsId === c.id); + }); + } credentials = credentials.map((c) => this.ownershipService.addOwnedByAndSharedWith(c)); } @@ -130,6 +143,20 @@ export class CredentialsService { ); if (isDefaultSelect) { + // Since we're filtering using project ID as part of the relation, + // we end up filtering out all the other relations, meaning that if + // it's shared to a project, it won't be able to find the home project. + // To solve this, we have to get all the relation now, even though + // we're deleting them later. + if ((options.listQueryOptions?.filter?.shared as { projectId?: string })?.projectId) { + const relations = await this.sharedCredentialsRepository.getAllRelationsForCredentials( + credentials.map((c) => c.id), + ); + credentials.forEach((c) => { + c.shared = relations.filter((r) => r.credentialsId === c.id); + }); + } + credentials = credentials.map((c) => this.ownershipService.addOwnedByAndSharedWith(c)); } diff --git a/packages/cli/src/databases/repositories/sharedCredentials.repository.ts b/packages/cli/src/databases/repositories/sharedCredentials.repository.ts index 8d2d1fa7af586..03acc24823ac5 100644 --- a/packages/cli/src/databases/repositories/sharedCredentials.repository.ts +++ b/packages/cli/src/databases/repositories/sharedCredentials.repository.ts @@ -151,4 +151,13 @@ export class SharedCredentialsRepository extends Repository { }) )?.project; } + + async getAllRelationsForCredentials(credentialIds: string[]) { + return await this.find({ + where: { + credentialsId: In(credentialIds), + }, + relations: ['project'], + }); + } } diff --git a/packages/cli/test/integration/credentials/credentials.api.test.ts b/packages/cli/test/integration/credentials/credentials.api.test.ts index cd66fbe467ef7..cd461b3dafe66 100644 --- a/packages/cli/test/integration/credentials/credentials.api.test.ts +++ b/packages/cli/test/integration/credentials/credentials.api.test.ts @@ -395,6 +395,21 @@ describe('GET /credentials', () => { expect(response2.body.data).toHaveLength(0); }); + test('should return homeProject when filtering credentials by projectId', async () => { + const project = await createTeamProject(undefined, member); + const credential = await saveCredential(payload(), { user: owner, role: 'credential:owner' }); + await shareCredentialWithProjects(credential, [project]); + + const response: GetAllResponse = await testServer + .authAgentFor(member) + .get('/credentials') + .query(`filter={ "projectId": "${project.id}" }`) + .expect(200); + + expect(response.body.data).toHaveLength(1); + expect(response.body.data[0].homeProject).not.toBeNull(); + }); + test('should return all credentials in a team project that member is part of', async () => { const teamProjectWithMember = await createTeamProject('Team Project With member', owner); void (await linkUserToProject(member, teamProjectWithMember, 'project:editor'));