From 988d3cbea63b1e1440ee4f7596477be6d2231973 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Tue, 1 Apr 2025 16:29:13 +0200 Subject: [PATCH 1/2] feat: Implement isOwner flag to apps get flows API endpoint --- packages/backend/src/controllers/api/v1/apps/get-flows.js | 5 +++++ .../backend/src/controllers/api/v1/apps/get-flows.test.js | 6 ++++-- packages/backend/test/mocks/rest/api/v1/apps/get-flows.js | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/controllers/api/v1/apps/get-flows.js b/packages/backend/src/controllers/api/v1/apps/get-flows.js index 21f58295..953fbbcd 100644 --- a/packages/backend/src/controllers/api/v1/apps/get-flows.js +++ b/packages/backend/src/controllers/api/v1/apps/get-flows.js @@ -1,5 +1,6 @@ import { renderObject } from '../../../../helpers/renderer.js'; import App from '../../../../models/app.js'; +import Flow from '../../../../models/flow.js'; import paginateRest from '../../../../helpers/pagination.js'; export default async (request, response) => { @@ -14,6 +15,10 @@ export default async (request, response) => { .withGraphFetched({ steps: true, }) + .select('flows.*') + .select( + Flow.raw('flows.user_id = ? as "isOwner"', [request.currentUser.id]) + ) .where('steps.app_key', app.key) .orderBy('active', 'desc') .orderBy('updated_at', 'desc'); diff --git a/packages/backend/src/controllers/api/v1/apps/get-flows.test.js b/packages/backend/src/controllers/api/v1/apps/get-flows.test.js index d23667ca..c333c128 100644 --- a/packages/backend/src/controllers/api/v1/apps/get-flows.test.js +++ b/packages/backend/src/controllers/api/v1/apps/get-flows.test.js @@ -59,7 +59,8 @@ describe('GET /api/v1/apps/:appKey/flows', () => { const expectedPayload = await getFlowsMock( [currentUserFlowOne], - [triggerStepFlowOne, actionStepFlowOne] + [triggerStepFlowOne, actionStepFlowOne], + currentUser.id ); expect(response.body).toStrictEqual(expectedPayload); @@ -107,7 +108,8 @@ describe('GET /api/v1/apps/:appKey/flows', () => { const expectedPayload = await getFlowsMock( [anotherUserFlowOne], - [triggerStepFlowOne, actionStepFlowOne] + [triggerStepFlowOne, actionStepFlowOne], + currentUser.id ); expect(response.body).toStrictEqual(expectedPayload); diff --git a/packages/backend/test/mocks/rest/api/v1/apps/get-flows.js b/packages/backend/test/mocks/rest/api/v1/apps/get-flows.js index 6012a6f6..7cd00fd8 100644 --- a/packages/backend/test/mocks/rest/api/v1/apps/get-flows.js +++ b/packages/backend/test/mocks/rest/api/v1/apps/get-flows.js @@ -1,4 +1,4 @@ -const getFlowsMock = async (flows, steps) => { +const getFlowsMock = async (flows, steps, currentUserId) => { const data = flows.map((flow) => { const flowSteps = steps.filter((step) => step.flowId === flow.id); @@ -7,6 +7,7 @@ const getFlowsMock = async (flows, steps) => { id: flow.id, name: flow.name, status: flow.active ? 'published' : 'draft', + isOwner: flow.userId === currentUserId, createdAt: flow.createdAt.getTime(), updatedAt: flow.updatedAt.getTime(), steps: flowSteps.map((step) => ({ From 1ecf1af24b93a75a91d4975bb09d32049da186a9 Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Tue, 1 Apr 2025 16:30:42 +0200 Subject: [PATCH 2/2] feat: Implement isOwner flag for connections get flows API endpoint --- .../backend/src/controllers/api/v1/connections/get-flows.js | 5 +++++ .../src/controllers/api/v1/connections/get-flows.test.js | 6 ++++-- .../backend/test/mocks/rest/api/v1/connections/get-flows.js | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/controllers/api/v1/connections/get-flows.js b/packages/backend/src/controllers/api/v1/connections/get-flows.js index c2b1069a..8bac6191 100644 --- a/packages/backend/src/controllers/api/v1/connections/get-flows.js +++ b/packages/backend/src/controllers/api/v1/connections/get-flows.js @@ -1,5 +1,6 @@ import { renderObject } from '../../../../helpers/renderer.js'; import paginateRest from '../../../../helpers/pagination.js'; +import Flow from '../../../../models/flow.js'; export default async (request, response) => { const flowsQuery = request.currentUser.authorizedFlows @@ -11,6 +12,10 @@ export default async (request, response) => { .withGraphFetched({ steps: true, }) + .select('flows.*') + .select( + Flow.raw('flows.user_id = ? as "isOwner"', [request.currentUser.id]) + ) .where('steps.connection_id', request.params.connectionId) .orderBy('active', 'desc') .orderBy('updated_at', 'desc'); diff --git a/packages/backend/src/controllers/api/v1/connections/get-flows.test.js b/packages/backend/src/controllers/api/v1/connections/get-flows.test.js index eb824a7e..f90da298 100644 --- a/packages/backend/src/controllers/api/v1/connections/get-flows.test.js +++ b/packages/backend/src/controllers/api/v1/connections/get-flows.test.js @@ -66,7 +66,8 @@ describe('GET /api/v1/connections/:connectionId/flows', () => { const expectedPayload = await getFlowsMock( [currentUserFlowOne], - [triggerStepFlowOne, actionStepFlowOne] + [triggerStepFlowOne, actionStepFlowOne], + currentUser.id ); expect(response.body).toStrictEqual(expectedPayload); @@ -120,7 +121,8 @@ describe('GET /api/v1/connections/:connectionId/flows', () => { const expectedPayload = await getFlowsMock( [anotherUserFlowOne], - [triggerStepFlowOne, actionStepFlowOne] + [triggerStepFlowOne, actionStepFlowOne], + currentUser.id ); expect(response.body).toStrictEqual(expectedPayload); diff --git a/packages/backend/test/mocks/rest/api/v1/connections/get-flows.js b/packages/backend/test/mocks/rest/api/v1/connections/get-flows.js index 6012a6f6..7cd00fd8 100644 --- a/packages/backend/test/mocks/rest/api/v1/connections/get-flows.js +++ b/packages/backend/test/mocks/rest/api/v1/connections/get-flows.js @@ -1,4 +1,4 @@ -const getFlowsMock = async (flows, steps) => { +const getFlowsMock = async (flows, steps, currentUserId) => { const data = flows.map((flow) => { const flowSteps = steps.filter((step) => step.flowId === flow.id); @@ -7,6 +7,7 @@ const getFlowsMock = async (flows, steps) => { id: flow.id, name: flow.name, status: flow.active ? 'published' : 'draft', + isOwner: flow.userId === currentUserId, createdAt: flow.createdAt.getTime(), updatedAt: flow.updatedAt.getTime(), steps: flowSteps.map((step) => ({