mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
fix(core): Return homeProject when filtering workflows by project id (#12077)
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
This commit is contained in:
parent
596f22103c
commit
efafeed334
|
@ -211,4 +211,13 @@ export class SharedWorkflowRepository extends Repository<SharedWorkflow> {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAllRelationsForWorkflows(workflowIds: string[]) {
|
||||||
|
return await this.find({
|
||||||
|
where: {
|
||||||
|
workflowId: In(workflowIds),
|
||||||
|
},
|
||||||
|
relations: ['project'],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,8 @@ export class WorkflowRepository extends Repository<WorkflowEntity> {
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMany(sharedWorkflowIds: string[], options?: ListQuery.Options) {
|
async getMany(sharedWorkflowIds: string[], originalOptions: ListQuery.Options = {}) {
|
||||||
|
const options = structuredClone(originalOptions);
|
||||||
if (sharedWorkflowIds.length === 0) return { workflows: [], count: 0 };
|
if (sharedWorkflowIds.length === 0) return { workflows: [], count: 0 };
|
||||||
|
|
||||||
if (typeof options?.filter?.projectId === 'string' && options.filter.projectId !== '') {
|
if (typeof options?.filter?.projectId === 'string' && options.filter.projectId !== '') {
|
||||||
|
|
|
@ -66,6 +66,20 @@ export class WorkflowService {
|
||||||
let { workflows, count } = await this.workflowRepository.getMany(sharedWorkflowIds, options);
|
let { workflows, count } = await this.workflowRepository.getMany(sharedWorkflowIds, options);
|
||||||
|
|
||||||
if (hasSharing(workflows)) {
|
if (hasSharing(workflows)) {
|
||||||
|
// 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 (typeof options?.filter?.projectId === 'string' && options.filter.projectId !== '') {
|
||||||
|
const relations = await this.sharedWorkflowRepository.getAllRelationsForWorkflows(
|
||||||
|
workflows.map((c) => c.id),
|
||||||
|
);
|
||||||
|
workflows.forEach((c) => {
|
||||||
|
c.shared = relations.filter((r) => r.workflowId === c.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
workflows = workflows.map((w) => this.ownershipService.addOwnedByAndSharedWith(w));
|
workflows = workflows.map((w) => this.ownershipService.addOwnedByAndSharedWith(w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +89,8 @@ export class WorkflowService {
|
||||||
}
|
}
|
||||||
|
|
||||||
workflows.forEach((w) => {
|
workflows.forEach((w) => {
|
||||||
// @ts-expect-error: This is to emulate the old behaviour of removing the shared
|
// This is to emulate the old behaviour of removing the shared field as
|
||||||
// field as part of `addOwnedByAndSharedWith`. We need this field in `addScopes`
|
// part of `addOwnedByAndSharedWith`. We need this field in `addScopes`
|
||||||
// though. So to avoid leaking the information we just delete it.
|
// though. So to avoid leaking the information we just delete it.
|
||||||
delete w.shared;
|
delete w.shared;
|
||||||
});
|
});
|
||||||
|
|
|
@ -17,10 +17,14 @@ import { EnterpriseWorkflowService } from '@/workflows/workflow.service.ee';
|
||||||
|
|
||||||
import { mockInstance } from '../../shared/mocking';
|
import { mockInstance } from '../../shared/mocking';
|
||||||
import { saveCredential } from '../shared/db/credentials';
|
import { saveCredential } from '../shared/db/credentials';
|
||||||
import { createTeamProject, linkUserToProject } from '../shared/db/projects';
|
import { createTeamProject, getPersonalProject, linkUserToProject } from '../shared/db/projects';
|
||||||
import { createTag } from '../shared/db/tags';
|
import { createTag } from '../shared/db/tags';
|
||||||
import { createManyUsers, createMember, createOwner } from '../shared/db/users';
|
import { createManyUsers, createMember, createOwner } from '../shared/db/users';
|
||||||
import { createWorkflow, shareWorkflowWithProjects } from '../shared/db/workflows';
|
import {
|
||||||
|
createWorkflow,
|
||||||
|
shareWorkflowWithProjects,
|
||||||
|
shareWorkflowWithUsers,
|
||||||
|
} from '../shared/db/workflows';
|
||||||
import { randomCredentialPayload } from '../shared/random';
|
import { randomCredentialPayload } from '../shared/random';
|
||||||
import * as testDb from '../shared/test-db';
|
import * as testDb from '../shared/test-db';
|
||||||
import type { SuperAgentTest } from '../shared/types';
|
import type { SuperAgentTest } from '../shared/types';
|
||||||
|
@ -676,6 +680,21 @@ describe('GET /workflows', () => {
|
||||||
|
|
||||||
expect(response2.body.data).toHaveLength(0);
|
expect(response2.body.data).toHaveLength(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should return homeProject when filtering workflows by projectId', async () => {
|
||||||
|
const workflow = await createWorkflow({ name: 'First' }, owner);
|
||||||
|
await shareWorkflowWithUsers(workflow, [member]);
|
||||||
|
const pp = await getPersonalProject(member);
|
||||||
|
|
||||||
|
const response = await authMemberAgent
|
||||||
|
.get('/workflows')
|
||||||
|
.query(`filter={ "projectId": "${pp.id}" }`)
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
expect(response.body.data).toHaveLength(1);
|
||||||
|
expect(response.body.data[0].id).toBe(workflow.id);
|
||||||
|
expect(response.body.data[0].homeProject).not.toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('select', () => {
|
describe('select', () => {
|
||||||
|
|
Loading…
Reference in a new issue